-
Notifications
You must be signed in to change notification settings - Fork 367
/
HtmlTag.cs
153 lines (133 loc) · 4.56 KB
/
HtmlTag.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
namespace Microsoft.DotNet.Interactive.Formatting;
/// <summary>
/// Represents an HTML tag.
/// </summary>
public class HtmlTag : IHtmlContent
{
private HtmlAttributes _htmlAttributes;
/// <summary>
/// Initializes a new instance of the <see cref="HtmlTag"/> class.
/// </summary>
/// <param name="name">The name of the tag.</param>
public HtmlTag(string name)
{
Name = name;
}
/// <summary>
/// Initializes a new instance of the <see cref="HtmlTag"/> class.
/// </summary>
/// <param name="name">The name of the tag.</param>
/// <param name="text">The text contained by the tag.</param>
public HtmlTag(string name, string text) : this(name)
{
Content = Write;
void Write(FormatContext context) => context.Writer.Write(text);
}
/// <summary>
/// Initializes a new instance of the <see cref="HtmlTag"/> class.
/// </summary>
/// <param name="name">Name of the tag.</param>
/// <param name="content">The content.</param>
public HtmlTag(string name, Action<FormatContext> content) : this(name)
{
Content = content;
}
public Action<FormatContext> Content { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is self closing.
/// </summary>
/// <value>
/// <c>true</c> if this instance is self closing; otherwise, <c>false</c>.
/// </value>
public bool IsSelfClosing { get; set; }
/// <summary>
/// Gets HTML tag type.
/// </summary>
/// <value>
/// The type of the tag.
/// </value>
public string Name { get; set; }
/// <summary>
/// Gets the HTML attributes to be rendered into the tag.
/// </summary>
/// <value>
/// The HTML attributes.
/// </value>
public HtmlAttributes HtmlAttributes
{
get => _htmlAttributes ??= new HtmlAttributes();
set => _htmlAttributes = value;
}
/// <inheritdoc />
public virtual void WriteTo(TextWriter writer, HtmlEncoder encoder = null)
{
WriteTo(new FormatContext(writer));
}
public void WriteTo(FormatContext context)
{
if (Content is null && IsSelfClosing)
{
WriteSelfClosingTag(context.Writer);
return;
}
WriteStartTag(context.Writer);
WriteContentsTo(context);
WriteEndTag(context.Writer);
}
protected void WriteSelfClosingTag(TextWriter writer)
{
writer.Write('<');
writer.Write(Name);
HtmlAttributes.WriteTo(writer, HtmlEncoder.Default);
writer.Write(" />");
}
protected void WriteEndTag(TextWriter writer)
{
writer.Write("</");
writer.Write(Name);
writer.Write('>');
}
protected void WriteStartTag(TextWriter writer)
{
writer.Write('<');
writer.Write(Name);
HtmlAttributes.WriteTo(writer, HtmlEncoder.Default);
writer.Write('>');
}
/// <summary>
/// Writes the tag contents (without outer HTML elements) to the specified writer.
/// </summary>
/// <param name = "writer">The writer.</param>
/// <param name="context">The context for the current format operation.</param>
protected virtual void WriteContentsTo(FormatContext context)
{
Content?.Invoke(context);
}
/// <summary>
/// Merges the specified attributes into the tag's existing attributes.
/// </summary>
/// <param name="htmlAttributes">The HTML attributes to be merged.</param>
/// <param name="replace">if set to <c>true</c> replace existing attributes when attributes with the same name have been previously defined; otherwise, ignore.</param>
public void MergeAttributes(IDictionary<string, object> htmlAttributes, bool replace = false) =>
HtmlAttributes.MergeWith(htmlAttributes, replace);
/// <summary>
/// Returns a <see cref = "System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref = "System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
var writer = new StringWriter(CultureInfo.InvariantCulture);
WriteTo(writer, HtmlEncoder.Default);
return writer.ToString();
}
}