diff --git a/YaeBlog.Core/Extensions/WebApplicationBuilderExtensions.cs b/YaeBlog.Core/Extensions/WebApplicationBuilderExtensions.cs index b4a6cd1..ff8c570 100644 --- a/YaeBlog.Core/Extensions/WebApplicationBuilderExtensions.cs +++ b/YaeBlog.Core/Extensions/WebApplicationBuilderExtensions.cs @@ -24,6 +24,8 @@ public static class WebApplicationBuilderExtensions builder.Services.AddSingleton(provider => provider.GetRequiredService()); builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services.AddTransient(provider => provider.GetRequiredService>().Value); diff --git a/YaeBlog.Core/Extensions/WebApplicationExtensions.cs b/YaeBlog.Core/Extensions/WebApplicationExtensions.cs index f541f4a..4ab3d8e 100644 --- a/YaeBlog.Core/Extensions/WebApplicationExtensions.cs +++ b/YaeBlog.Core/Extensions/WebApplicationExtensions.cs @@ -8,11 +8,11 @@ namespace YaeBlog.Core.Extensions; public static class WebApplicationExtensions { - public static WebApplication UseMiddleRenderProcessors(this WebApplication application) + public static void UseYaeBlog(this WebApplication application) { application.UsePostRenderProcessor(); - - return application; + application.UsePostRenderProcessor(); + application.UsePostRenderProcessor(); } private static void UsePreRenderProcessor(this WebApplication application) where T : IPreRenderProcessor diff --git a/YaeBlog.Core/Processors/CodeBlockPostRenderProcessor.cs b/YaeBlog.Core/Processors/CodeBlockPostRenderProcessor.cs new file mode 100644 index 0000000..217aa38 --- /dev/null +++ b/YaeBlog.Core/Processors/CodeBlockPostRenderProcessor.cs @@ -0,0 +1,29 @@ +using AngleSharp; +using AngleSharp.Dom; +using YaeBlog.Core.Abstractions; +using YaeBlog.Core.Models; + +namespace YaeBlog.Core.Processors; + +public class CodeBlockPostRenderProcessor : IPostRenderProcessor +{ + public async Task ProcessAsync(BlogEssay essay) + { + BrowsingContext context = new(Configuration.Default); + IDocument document = await context.OpenAsync( + req => req.Content(essay.HtmlContent)); + + IEnumerable preElements = from e in document.All + where e.LocalName == "pre" + select e; + + foreach (IElement element in preElements) + { + element.ClassList.Add("p-3 text-bg-secondary rounded-1"); + } + + return essay.WithNewHtmlContent(document.DocumentElement.OuterHtml); + } + + public string Name => nameof(CodeBlockPostRenderProcessor); +} diff --git a/YaeBlog.Core/Processors/ImagePostRenderProcessor.cs b/YaeBlog.Core/Processors/ImagePostRenderProcessor.cs index d4a61a8..0592899 100644 --- a/YaeBlog.Core/Processors/ImagePostRenderProcessor.cs +++ b/YaeBlog.Core/Processors/ImagePostRenderProcessor.cs @@ -38,7 +38,7 @@ public class ImagePostRenderProcessor(ILogger logger, return essay.WithNewHtmlContent(html.DocumentElement.OuterHtml); } - public string Name => "ImagePostRenderProcessor"; + public string Name => nameof(ImagePostRenderProcessor); private string GenerateImageLink(string filename, string essayFilename) { diff --git a/YaeBlog.Core/Processors/TablePostRenderProcessor.cs b/YaeBlog.Core/Processors/TablePostRenderProcessor.cs new file mode 100644 index 0000000..e2c3444 --- /dev/null +++ b/YaeBlog.Core/Processors/TablePostRenderProcessor.cs @@ -0,0 +1,34 @@ +using AngleSharp; +using AngleSharp.Dom; +using AngleSharp.Html.Dom; +using YaeBlog.Core.Abstractions; +using YaeBlog.Core.Models; + +namespace YaeBlog.Core.Processors; + +public class TablePostRenderProcessor: IPostRenderProcessor +{ + public async Task ProcessAsync(BlogEssay essay) + { + BrowsingContext browsingContext = new(Configuration.Default); + IDocument document = await browsingContext.OpenAsync( + req => req.Content(essay.HtmlContent)); + + IEnumerable tableElements = from item in document.All + where item.LocalName == "table" + select item as IHtmlTableElement; + + foreach (IHtmlTableElement element in tableElements) + { + IHtmlDivElement divElement = document.CreateElement(); + divElement.InnerHtml = element.OuterHtml; + divElement.ClassList.Add("py-2", "table-wrapper"); + + element.Replace(divElement); + } + + return essay.WithNewHtmlContent(document.DocumentElement.OuterHtml); + } + + public string Name => nameof(TablePostRenderProcessor); +} diff --git a/YaeBlog/Components/App.razor b/YaeBlog/Components/App.razor index d9b1f57..3a96ded 100644 --- a/YaeBlog/Components/App.razor +++ b/YaeBlog/Components/App.razor @@ -19,6 +19,10 @@ + + diff --git a/YaeBlog/Program.cs b/YaeBlog/Program.cs index a8f53aa..dd92dde 100644 --- a/YaeBlog/Program.cs +++ b/YaeBlog/Program.cs @@ -13,7 +13,7 @@ WebApplication application = builder.Build(); application.UseStaticFiles(); application.UseAntiforgery(); -application.UseMiddleRenderProcessors(); +application.UseYaeBlog(); application.MapRazorComponents() .AddInteractiveServerRenderMode(); diff --git a/YaeBlog/wwwroot/clipboard.min.js b/YaeBlog/wwwroot/clipboard.min.js new file mode 100644 index 0000000..1103f81 --- /dev/null +++ b/YaeBlog/wwwroot/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1