-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added IHtmlDocument to simplify the standardized parts of HTML docume…
…nt generation.
- Loading branch information
1 parent
8d98564
commit bfd57eb
Showing
6 changed files
with
169 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,40 @@ | ||
using HtmlUtilities; | ||
using HtmlUtilities.Validated; | ||
|
||
var app = WebApplication.CreateBuilder(args).Build(); | ||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
app.MapFallback(async (HttpResponse response, CancellationToken cancellationToken) => | ||
{ | ||
response.ContentType = "text/html; charset=utf-8"; | ||
builder.WebHost.ConfigureKestrel(options => options.AddServerHeader = false); | ||
|
||
await HtmlWriter.WriteDocumentAsync(response.BodyWriter, attributes => attributes.Write("lang", "en-us"), async (children, cancellationToken) => | ||
{ | ||
children.WriteElement("head", null, children => | ||
{ | ||
children.WriteElementSelfClosing("meta", attributes => attributes.Write("charset", "utf-8")); | ||
children.WriteElement("title", null, children => children.WriteText("Hello World!")); | ||
}); //head | ||
var app = builder.Build(); | ||
|
||
await children.WriteElementAsync("body", null, async (children, cancellationToken) => | ||
{ | ||
children.WriteElement("p", null, children => children.WriteText("First bytes.")); | ||
app.MapFallback((HttpContext context) => | ||
context.WriteDocumentAsync(new TestDocument())); | ||
|
||
await response.BodyWriter.FlushAsync(cancellationToken).ConfigureAwait(false); | ||
await Task.Delay(1000, cancellationToken).ConfigureAwait(false); | ||
await app.RunAsync().ConfigureAwait(false); | ||
|
||
children.WriteElement("p", null, children => children.WriteText("Second bytes after a delay.")); | ||
}, cancellationToken).ConfigureAwait(false); // body | ||
}, cancellationToken).ConfigureAwait(false); | ||
class TestDocument : IHtmlDocument | ||
{ | ||
ValidatedAttributeValue IHtmlDocument.Language => "en-us"; | ||
ValidatedText IHtmlDocument.Title => "Hello World!"; | ||
ValidatedAttributeValue IHtmlDocument.Description => "Test page for HTML Utilities"; | ||
|
||
await response.BodyWriter.FlushAsync(cancellationToken).ConfigureAwait(false); | ||
}); | ||
Task IHtmlDocument.WriteBodyContentsAsync(HtmlWriter writer, CancellationToken cancellationToken) | ||
{ | ||
writer.WriteElement("p", null, children => children.WriteText("Test bytes.")); | ||
return Task.CompletedTask; | ||
} | ||
} | ||
|
||
app.Run(); | ||
static class Extensions | ||
{ | ||
public static Task WriteDocumentAsync(this HttpContext context, IHtmlDocument document) | ||
{ | ||
var request = context.Request; | ||
var response = context.Response; | ||
response.ContentType = "text/html; charset=utf-8"; | ||
var baseUri = $"{request.Scheme}://{request.Host}/"; | ||
response.Headers.ContentSecurityPolicy = $"default-src {baseUri}; base-uri {baseUri}"; | ||
|
||
return document.WriteAsync(response.BodyWriter, context.RequestAborted); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using System.Buffers; | ||
|
||
namespace HtmlUtilities; | ||
|
||
/// <summary> | ||
/// Provides extended functionality for <see cref="IHtmlDocument"/> implementations. | ||
/// </summary> | ||
public static class HtmlDocumentExtensions | ||
{ | ||
/// <summary> | ||
/// Writes the document to <paramref name="writer"/>. | ||
/// </summary> | ||
/// <param name="document">The document to write.</param> | ||
/// <param name="writer">Receives the written document.</param> | ||
/// <param name="cancellationToken">Cancels emission of document data.</param> | ||
/// <returns></returns> | ||
public static async Task WriteAsync( | ||
this IHtmlDocument document, | ||
IBufferWriter<byte> writer, | ||
CancellationToken cancellationToken = default) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
writer.Write("<!DOCTYPE html><html"u8); | ||
|
||
byte[]? validated; | ||
|
||
if ((validated = document.Language.value) is not null) | ||
{ | ||
writer.Write(" lang"u8); | ||
writer.Write(validated); | ||
} | ||
|
||
writer.Write("><head><meta charset=utf-8><meta name=viewport content=\"width=device-width, initial-scale=1\">"u8); | ||
|
||
|
||
if ((validated = document.Title.value) is not null) | ||
{ | ||
writer.Write("<title>"u8); | ||
writer.Write(validated); | ||
writer.Write("</title>"u8); | ||
} | ||
|
||
if ((validated = document.Description.value) is not null) | ||
{ | ||
writer.Write("<meta name=description content"u8); | ||
writer.Write(validated); | ||
writer.Write(">"u8); | ||
} | ||
|
||
writer.Write("</head><body>"u8); | ||
|
||
await document.WriteBodyContentsAsync(new HtmlWriter(writer), cancellationToken).ConfigureAwait(false); | ||
|
||
writer.Write("</body></html>"u8); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using HtmlUtilities.Validated; | ||
using System.Buffers; | ||
|
||
namespace HtmlUtilities; | ||
|
||
/// <summary> | ||
/// Automatically handles many of the standard features of an HTML document. | ||
/// </summary> | ||
public interface IHtmlDocument | ||
{ | ||
/// <summary> | ||
/// The IETF language tag of the document's language. | ||
/// By default, this attribute is not emitted. | ||
/// </summary> | ||
ValidatedAttributeValue Language => new(); | ||
|
||
/// <summary> | ||
/// The document's title. | ||
/// By default, this attribute is not emitted. | ||
/// </summary> | ||
ValidatedText Title => new(); | ||
|
||
/// <summary> | ||
/// A description of the contents of the document. | ||
/// By default, this is not emitted. | ||
/// </summary> | ||
ValidatedAttributeValue Description => new(); | ||
|
||
/// <summary> | ||
/// Writes the content of an HTML document's body. | ||
/// </summary> | ||
/// <param name="writer">Receives the write commands.</param> | ||
/// <param name="cancellationToken">Indicates that the document is no longer needed so processing can be cancelled.</param> | ||
/// <returns>A task that, upon completion, indicates document writing is complete.</returns> | ||
/// <remarks>By default, directs the viewer to https://github.com/RyanLamansky/html-utilities to learn how to use this function.</remarks> | ||
Task WriteBodyContentsAsync(HtmlWriter writer, CancellationToken cancellationToken = default) | ||
{ | ||
writer.WriteElement("p", null, children => | ||
{ | ||
writer.WriteText("Visit "); | ||
writer.WriteElement("a", writer => | ||
{ | ||
writer.Write("href", "https://github.com/RyanLamansky/html-utilities"); | ||
}, | ||
writer => | ||
{ | ||
writer.WriteText("https://github.com/RyanLamansky/html-utilities"); | ||
}); | ||
writer.WriteText(" to learn how to customize an HtmlDocument instance."); | ||
}); | ||
|
||
return Task.CompletedTask; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters