XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
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);
    }
}