namespace XFESystem.Documents;
public sealed partial class DocumentPreviewBuilder
{
/// <summary>
/// The website's article component, for the system's own web renderer. The
/// caller must serve this page and WebResources at the same bundled origin.
/// This API never executes scripts contained in the Markdown source.
/// </summary>
public PreviewDocument MarkdownWeb(string text, string title = "Markdown", string language = "zh-CN", bool dark = true) =>
BuildWebsite(markdownRenderer.RenderHtml(text), title, language, dark);
public PreviewDocument CodeWeb(string text, string path, string language = "zh-CN", bool dark = true) =>
BuildWebsite($"<pre data-code-block-tools><code class=\"language-{CodeHighlightLanguage.FromPath(path)}\">{E(text)}</code></pre>",
path, language, dark);
private static PreviewDocument BuildWebsite(string body, string title, string language, bool dark)
{
// These orders are the shared website partials' order, following the
// Bootstrap/theme sheets in _Layout and docs-layout in Docs/View.
string[] styles = ["/css/bootstrap.min.css", "/css/theme-variables.css", "/css/bootstrap-icons.min.css",
"/css/docs/code-style.css", "/css/docs/markdown-style.css", "/css/docs/log.css", "/css/docs/terminal.css",
"/css/docs/katex.min.css", "/css/docs/docs-layout.css"];
string[] scripts = ["/js/docs/highlight.min.js", "/js/docs/xaml.js", "/js/docs/csharp.js", "/js/docs/bash.js",
"/js/docs/powershell.js", "/js/docs/dos.js", "/js/docs/log.js", "/js/docs/plaintext.js",
"/js/docs/katex.min.js", "/js/docs/auto-render.min.js", "/js/docs/doc-utils.js", "/js/docs/code-block-tools.js",
"/js/docs/docs-reader.js"];
var links = string.Join("\n", styles.Select(path => $"<link rel=\"stylesheet\" href=\"{path}\">"));
var includes = string.Join("\n", scripts.Select(path => $"<script src=\"{path}\"></script>"));
var theme = dark ? "dark" : "light";
var html = $$"""
<!doctype html><html lang="{{E(language)}}" class="{{(dark ? "dark" : "")}}" data-bs-theme="{{theme}}"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{E(title)}}</title>
{{links}}
</head><body class="docs-reader-page">
<main class="docs-content"><article class="docs-article">
<div class="markdown-body docs-article-body" data-doc-content data-no-localize>{{body}}</div>
</article></main>
{{includes}}
</body></html>
""";
// BrowserService currently treats declared CSP as unsupported and
// blocks author scripts. Do not pretend that omission implements CSP:
// the resource host must apply this explicit local-only policy, and may
// not serve arbitrary caller HTML from its trusted packaged origin.
const string policy = "default-src 'none'; script-src 'self'; style-src 'self'; font-src 'self'; " +
"img-src data: blob:; connect-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'";
return new PreviewDocument(html, true, policy);
}
}
namespace XFESystem.Documents;
public sealed partial class DocumentPreviewBuilder
{
/// <summary>
/// The website's article component, for the system's own web renderer. The
/// caller must serve this page and WebResources at the same bundled origin.
/// This API never executes scripts contained in the Markdown source.
/// </summary>
public PreviewDocument MarkdownWeb(string text, string title = "Markdown", string language = "zh-CN", bool dark = true) =>
BuildWebsite(markdownRenderer.RenderHtml(text), title, language, dark);
public PreviewDocument CodeWeb(string text, string path, string language = "zh-CN", bool dark = true) =>
BuildWebsite($"<pre data-code-block-tools><code class=\"language-{CodeHighlightLanguage.FromPath(path)}\">{E(text)}</code></pre>",
path, language, dark);
private static PreviewDocument BuildWebsite(string body, string title, string language, bool dark)
{
// These orders are the shared website partials' order, following the
// Bootstrap/theme sheets in _Layout and docs-layout in Docs/View.
string[] styles = ["/css/bootstrap.min.css", "/css/theme-variables.css", "/css/bootstrap-icons.min.css",
"/css/docs/code-style.css", "/css/docs/markdown-style.css", "/css/docs/log.css", "/css/docs/terminal.css",
"/css/docs/katex.min.css", "/css/docs/docs-layout.css"];
string[] scripts = ["/js/docs/highlight.min.js", "/js/docs/xaml.js", "/js/docs/csharp.js", "/js/docs/bash.js",
"/js/docs/powershell.js", "/js/docs/dos.js", "/js/docs/log.js", "/js/docs/plaintext.js",
"/js/docs/katex.min.js", "/js/docs/auto-render.min.js", "/js/docs/doc-utils.js", "/js/docs/code-block-tools.js",
"/js/docs/docs-reader.js"];
var links = string.Join("\n", styles.Select(path => $"<link rel=\"stylesheet\" href=\"{path}\">"));
var includes = string.Join("\n", scripts.Select(path => $"<script src=\"{path}\"></script>"));
var theme = dark ? "dark" : "light";
var html = $$"""
<!doctype html><html lang="{{E(language)}}" class="{{(dark ? "dark" : "")}}" data-bs-theme="{{theme}}"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{E(title)}}</title>
{{links}}
</head><body class="docs-reader-page">
<main class="docs-content"><article class="docs-article">
<div class="markdown-body docs-article-body" data-doc-content data-no-localize>{{body}}</div>
</article></main>
{{includes}}
</body></html>
""";
// BrowserService currently treats declared CSP as unsupported and
// blocks author scripts. Do not pretend that omission implements CSP:
// the resource host must apply this explicit local-only policy, and may
// not serve arbitrary caller HTML from its trusted packaged origin.
const string policy = "default-src 'none'; script-src 'self'; style-src 'self'; font-src 'self'; " +
"img-src data: blob:; connect-src 'none'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'";
return new PreviewDocument(html, true, policy);
}
}