HtmlDomBuilderExtensions
Extensions to be used exclusively by the DOM Builder.
using AngleSharp.Common;
using AngleSharp.Dom;
using AngleSharp.Html.Construction;
using AngleSharp.Html.Parser.Tokens;
using AngleSharp.Html.Parser.Tokens.Struct;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace AngleSharp.Html.Parser
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal static class HtmlDomBuilderExtensions
{
public static HtmlTreeMode? SelectMode(this IConstructableElement element, bool isLast, Stack<HtmlTreeMode> templateModes)
{
if (element.Flags.HasFlag(NodeFlags.HtmlMember)) {
StringOrMemory localName = element.LocalName;
if (localName.Is(TagNames.Select))
return HtmlTreeMode.InSelect;
if (TagNames.AllTableCells.Contains(localName))
return isLast ? HtmlTreeMode.InBody : HtmlTreeMode.InCell;
if (localName.Is(TagNames.Tr))
return HtmlTreeMode.InRow;
if (TagNames.AllTableSections.Contains(localName))
return HtmlTreeMode.InTableBody;
if (localName.Is(TagNames.Body))
return HtmlTreeMode.InBody;
if (localName.Is(TagNames.Table))
return HtmlTreeMode.InTable;
if (localName.Is(TagNames.Caption))
return HtmlTreeMode.InCaption;
if (localName.Is(TagNames.Colgroup))
return HtmlTreeMode.InColumnGroup;
if (localName.Is(TagNames.Template) && templateModes.Count > 0)
return templateModes.Peek();
if (localName.Is(TagNames.Html))
return HtmlTreeMode.BeforeHead;
if (localName.Is(TagNames.Head))
return isLast ? HtmlTreeMode.InBody : HtmlTreeMode.InHead;
if (localName.Is(TagNames.Frameset))
return HtmlTreeMode.InFrameset;
}
if (isLast)
return HtmlTreeMode.InBody;
return null;
}
public static int GetCode(this HtmlParseError code)
{
return (int)code;
}
public static void SetUniqueAttributes<TElement>(this TElement element, ref StructHtmlToken token) where TElement : class, IConstructableElement
{
StructAttributes attributes = token.Attributes;
for (int num = attributes.Count - 1; num >= 0; num--) {
attributes = token.Attributes;
if (element.HasAttribute(attributes[num].Name))
token.RemoveAttributeAt(num);
}
element.SetAttributes(token.Attributes);
}
public static void AddFormatting(this List<Element> formatting, Element element)
{
formatting.AddFormatting<Element>(element);
}
public static void AddFormatting<TElement>(this List<TElement> formatting, TElement element) where TElement : class, IConstructableElement
{
int num = 0;
for (int num2 = formatting.Count - 1; num2 >= 0; num2--) {
TElement val = formatting[num2];
if (val == null)
break;
if (val.NodeName.Is(element.NodeName) && val.NamespaceUri.Is(element.NamespaceUri) && val.Attributes.SameAs(element.Attributes) && ++num == 3) {
formatting.RemoveAt(num2);
break;
}
}
formatting.Add(element);
}
public static void ClearFormatting(this List<Element> formatting)
{
formatting.ClearFormatting<Element>();
}
public static void ClearFormatting<TElement>(this List<TElement> formatting) where TElement : class, IConstructableElement
{
while (formatting.Count != 0) {
int index = formatting.Count - 1;
TElement val = formatting[index];
formatting.RemoveAt(index);
if (val == null)
break;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AddScopeMarker(this List<Element> formatting)
{
formatting.AddScopeMarker<Element>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AddScopeMarker<TElement>(this List<TElement> formatting) where TElement : class, IConstructableElement
{
formatting.Add((TElement)null);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AddComment(this Element parent, HtmlToken token)
{
parent.AddNode(token.IsProcessingInstruction ? ((CharacterData)ProcessingInstruction.Create(parent.Owner, token.Data)) : ((CharacterData)new Comment(parent.Owner, token.Data)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AddComment(this Element parent, ref StructHtmlToken token)
{
StringOrMemory data;
object node;
if (!token.IsProcessingInstruction) {
Document owner = parent.Owner;
data = token.Data;
node = new Comment(owner, data.ToString());
} else {
Document owner2 = parent.Owner;
data = token.Data;
node = ProcessingInstruction.Create(owner2, data.ToString());
}
parent.AddNode((Node)node);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AddComment(this Document parent, HtmlToken token)
{
parent.AddNode(token.IsProcessingInstruction ? ((CharacterData)ProcessingInstruction.Create(parent, token.Data)) : ((CharacterData)new Comment(parent, token.Data)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AddComment(this Document parent, ref StructHtmlToken token)
{
StringOrMemory data;
object node;
if (!token.IsProcessingInstruction) {
data = token.Data;
node = new Comment(parent, data.ToString());
} else {
data = token.Data;
node = ProcessingInstruction.Create(parent, data.ToString());
}
parent.AddNode((Node)node);
}
public static QuirksMode GetQuirksMode(this HtmlDoctypeToken doctype)
{
if (doctype.IsFullQuirks)
return QuirksMode.On;
if (doctype.IsLimitedQuirks)
return QuirksMode.Limited;
return QuirksMode.Off;
}
public static QuirksMode GetQuirksMode(ref StructHtmlToken doctype)
{
if (doctype.IsFullQuirks)
return QuirksMode.On;
if (doctype.IsLimitedQuirks)
return QuirksMode.Limited;
return QuirksMode.Off;
}
}
}