2023-07-19 22:09:25 +00:00
|
|
|
|
using System;
|
2023-07-22 00:20:46 +00:00
|
|
|
|
using System.Collections.Generic;
|
2023-07-19 22:09:25 +00:00
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2023-07-22 00:20:46 +00:00
|
|
|
|
using Microsoft.AspNetCore.Mvc.Rendering;
|
2023-07-21 20:11:56 +00:00
|
|
|
|
using Cauldron.Core;
|
2023-07-19 22:09:25 +00:00
|
|
|
|
|
2023-07-21 20:11:56 +00:00
|
|
|
|
namespace Cauldron.Macos;
|
2023-07-19 22:09:25 +00:00
|
|
|
|
|
|
|
|
|
public static class ScriptRunner
|
|
|
|
|
{
|
|
|
|
|
public static void RunScript(MainWindow window)
|
|
|
|
|
{
|
|
|
|
|
window.SetScriptRunState(true);
|
2023-07-22 00:20:46 +00:00
|
|
|
|
|
|
|
|
|
TagBuilder body = new("body");
|
|
|
|
|
|
|
|
|
|
window.ScriptOutputWebView.SetOutputPanelContent(body);
|
2023-07-19 22:09:25 +00:00
|
|
|
|
TaskScheduler uiThread = TaskScheduler.FromCurrentSynchronizationContext();
|
|
|
|
|
|
2023-07-21 20:11:56 +00:00
|
|
|
|
CauldronWriter writer = new(obj =>
|
2023-07-19 22:09:25 +00:00
|
|
|
|
{
|
2023-07-22 00:20:46 +00:00
|
|
|
|
window.BeginInvokeOnMainThread(() =>
|
2023-07-19 22:09:25 +00:00
|
|
|
|
{
|
2023-07-22 00:20:46 +00:00
|
|
|
|
body.InnerHtml.AppendHtml(GenerateValueOutput(obj));
|
|
|
|
|
window.ScriptOutputWebView.SetOutputPanelContent(body);
|
|
|
|
|
});
|
2023-07-19 22:09:25 +00:00
|
|
|
|
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
window.ScriptCancellationTokenSource = new CancellationTokenSource();
|
|
|
|
|
|
|
|
|
|
string script = window.ScriptText;
|
|
|
|
|
|
|
|
|
|
Task task = Task
|
|
|
|
|
.Run(async () =>
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await RoslynHost.RunScript(script, Array.Empty<string>(),
|
|
|
|
|
new RoslynHostGlobals(writer),
|
|
|
|
|
window.ScriptCancellationTokenSource.Token);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
window.BeginInvokeOnMainThread(() =>
|
2023-07-22 00:20:46 +00:00
|
|
|
|
{
|
|
|
|
|
TagBuilder exTag = new("pre");
|
|
|
|
|
exTag.InnerHtml.Append(ex.ToString());
|
|
|
|
|
body.InnerHtml.AppendHtml(exTag);
|
|
|
|
|
|
|
|
|
|
window.ScriptOutputWebView.SetOutputPanelContent(body);
|
|
|
|
|
});
|
2023-07-19 22:09:25 +00:00
|
|
|
|
}
|
|
|
|
|
}, window.ScriptCancellationTokenSource.Token)
|
|
|
|
|
.ContinueWith((t) => window.SetScriptRunState(false),
|
|
|
|
|
uiThread);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-22 00:20:46 +00:00
|
|
|
|
private static TagBuilder GenerateValueOutput(object value)
|
|
|
|
|
{
|
|
|
|
|
if (value is string str)
|
|
|
|
|
{
|
|
|
|
|
TagBuilder tag = new("p");
|
|
|
|
|
tag.InnerHtml.Append(str);
|
|
|
|
|
return tag;
|
|
|
|
|
}
|
|
|
|
|
if (value.GetType().IsPrimitive)
|
|
|
|
|
{
|
|
|
|
|
TagBuilder tag = new("p");
|
|
|
|
|
tag.InnerHtml.Append(value.ToString());
|
|
|
|
|
return tag;
|
|
|
|
|
}
|
|
|
|
|
if (value is IEnumerable<object> enumberable)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SetOutputPanelContent(this WebKit.WKWebView webView,
|
|
|
|
|
TagBuilder body)
|
|
|
|
|
{
|
|
|
|
|
TagBuilder head = new("head");
|
2023-07-24 17:07:44 +00:00
|
|
|
|
TagBuilder style = new("style");
|
|
|
|
|
style.InnerHtml.AppendHtml(outputCss);
|
|
|
|
|
head.InnerHtml.AppendHtml(style);
|
2023-07-22 00:20:46 +00:00
|
|
|
|
|
|
|
|
|
string contents = "<!DOCTYPE html>"
|
|
|
|
|
+ head.RenderAsString()
|
|
|
|
|
+ body.RenderAsString();
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Contents: " + contents);
|
|
|
|
|
|
|
|
|
|
webView.LoadHtmlString(new Foundation.NSString(contents), null);
|
|
|
|
|
}
|
2023-07-24 17:07:44 +00:00
|
|
|
|
|
|
|
|
|
private const string outputCss = """
|
|
|
|
|
body {
|
|
|
|
|
font-family: -apple-system;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
* {
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.output-section {
|
|
|
|
|
margin-bottom: 1rem;
|
|
|
|
|
padding-left: 6px;
|
|
|
|
|
transition: box-shadow 250ms ease-in-out;
|
|
|
|
|
box-shadow: -2px 0 0 0 rgba(175, 82, 222, 0.25);
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
box-shadow: -4px 0 0 0 rgba(175, 82, 222, 0.5);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h2 {
|
|
|
|
|
font-size: 1.25rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
table {
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
margin-bottom: 1rem;
|
|
|
|
|
border: solid 1px lightgray;
|
|
|
|
|
|
|
|
|
|
caption {
|
|
|
|
|
margin-bottom: 0.5em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
th {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
text-align: center;
|
|
|
|
|
padding: 8px;
|
|
|
|
|
border-bottom: solid 1px lightgray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
th:not(:last-child) {
|
|
|
|
|
border-right: solid 1px lightgray;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
td {
|
|
|
|
|
padding: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tr:nth-child(even) {
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.065);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
code {
|
|
|
|
|
font-family: ui-monospace;
|
|
|
|
|
}
|
|
|
|
|
""";
|
2023-07-22 00:20:46 +00:00
|
|
|
|
}
|