AngleSharp by AngleSharp

<PackageReference Include="AngleSharp" Version="1.0.4-alpha-301" />

.NET API 888,832 bytes

 Node

Represents a node in the generated tree.
using AngleSharp.Html.Dom; using AngleSharp.Text; using System; using System.IO; using System.Runtime.CompilerServices; using System.Text; namespace AngleSharp.Dom { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public abstract class Node : EventTarget, INode, IEventTarget, IMarkupFormattable, IEquatable<INode> { private readonly NodeType _type; private readonly string _name; private readonly NodeFlags _flags; [System.Runtime.CompilerServices.Nullable(2)] private Url _baseUri; [System.Runtime.CompilerServices.Nullable(2)] private Node _parent; private NodeList _children; [System.Runtime.CompilerServices.Nullable(2)] private Document _owner; public NodeFlags Flags => _flags; public bool HasChildNodes => _children.Length != 0; public string BaseUri => BaseUrl?.Href ?? string.Empty; [System.Runtime.CompilerServices.Nullable(2)] public Url BaseUrl { [System.Runtime.CompilerServices.NullableContext(2)] get { if (_baseUri != null) return _baseUri; if (_parent != null) { foreach (Node item in this.Ancestors<Node>()) { if (item._baseUri != null) return item._baseUri; } } Document owner = Owner; if (owner != null) return owner._baseUri ?? owner.DocumentUrl; if (_type == NodeType.Document) { owner = (Document)this; return owner.DocumentUrl; } return null; } [System.Runtime.CompilerServices.NullableContext(2)] set { _baseUri = value; } } public NodeType NodeType => _type; public virtual string NodeValue { get { return null; } set { } } public virtual string TextContent { get { return null; } set { } } [System.Runtime.CompilerServices.Nullable(2)] INode INode.PreviousSibling { [System.Runtime.CompilerServices.NullableContext(2)] get { return PreviousSibling; } } [System.Runtime.CompilerServices.Nullable(2)] INode INode.NextSibling { [System.Runtime.CompilerServices.NullableContext(2)] get { return NextSibling; } } [System.Runtime.CompilerServices.Nullable(2)] INode INode.FirstChild { [System.Runtime.CompilerServices.NullableContext(2)] get { return FirstChild; } } [System.Runtime.CompilerServices.Nullable(2)] INode INode.LastChild { [System.Runtime.CompilerServices.NullableContext(2)] get { return LastChild; } } IDocument INode.Owner { get { return Owner; } } [System.Runtime.CompilerServices.Nullable(2)] INode INode.Parent { [System.Runtime.CompilerServices.NullableContext(2)] get { return _parent; } } [System.Runtime.CompilerServices.Nullable(2)] public IElement ParentElement { [System.Runtime.CompilerServices.NullableContext(2)] get { return _parent as IElement; } } INodeList INode.ChildNodes { get { return _children; } } public string NodeName => _name; [System.Runtime.CompilerServices.Nullable(2)] internal Node PreviousSibling { [System.Runtime.CompilerServices.NullableContext(2)] get { if (_parent != null) { int length = _parent._children.Length; for (int i = 1; i < length; i++) { if (_parent._children[i] == this) return _parent._children[i - 1]; } } return null; } } [System.Runtime.CompilerServices.Nullable(2)] internal Node NextSibling { [System.Runtime.CompilerServices.NullableContext(2)] get { if (_parent != null) { int num = _parent._children.Length - 1; for (int i = 0; i < num; i++) { if (_parent._children[i] == this) return _parent._children[i + 1]; } } return null; } } [System.Runtime.CompilerServices.Nullable(2)] internal Node FirstChild { [System.Runtime.CompilerServices.NullableContext(2)] get { if (_children.Length <= 0) return null; return _children[0]; } } [System.Runtime.CompilerServices.Nullable(2)] internal Node LastChild { [System.Runtime.CompilerServices.NullableContext(2)] get { if (_children.Length <= 0) return null; return _children[_children.Length - 1]; } } internal NodeList ChildNodes { get { return _children; } set { _children = value; } } [System.Runtime.CompilerServices.Nullable(2)] internal Node Parent { [System.Runtime.CompilerServices.NullableContext(2)] get { return _parent; } [System.Runtime.CompilerServices.NullableContext(2)] set { _parent = value; } } internal Document Owner { get { if (_type == NodeType.Document) return null; return _owner; } set { foreach (Node item in this.DescendentsAndSelf<Node>()) { Document owner = item.Owner; if (owner != value) { item._owner = value; if (owner != null) NodeIsAdopted(owner); } } } } public Node([System.Runtime.CompilerServices.Nullable(2)] Document owner, string name, NodeType type = NodeType.Element, NodeFlags flags = NodeFlags.None) { _owner = owner; _name = (name ?? string.Empty); _type = type; _children = (this.IsEndPoint() ? NodeList.Empty : new NodeList()); _flags = flags; } [System.Runtime.CompilerServices.NullableContext(2)] internal void ReplaceAll(Node node, bool suppressObservers) { Document owner = Owner; if (node != null) owner.AdoptNode(node); NodeList nodeList = new NodeList(); NodeList nodeList2 = new NodeList(); nodeList.AddRange(_children); if (node != null) { if (node.NodeType == NodeType.DocumentFragment) nodeList2.AddRange(node._children); else nodeList2.Add(node); } for (int i = 0; i < nodeList.Length; i++) { RemoveChild(nodeList[i], true); } for (int j = 0; j < nodeList2.Length; j++) { InsertBefore(nodeList2[j], null, true); } if (!suppressObservers) owner.QueueMutation(MutationRecord.ChildList(this, nodeList2, nodeList, null, null)); ReplacedAll(); } internal INode InsertBefore(Node newElement, [System.Runtime.CompilerServices.Nullable(2)] Node referenceElement, bool suppressObservers) { Document owner = Owner; int num = (newElement.NodeType != NodeType.DocumentFragment) ? 1 : newElement.ChildNodes.Length; if (referenceElement != null && owner != null) { int num2 = referenceElement.Index(); foreach (Range attachedReference in owner.GetAttachedReferences<Range>()) { if (attachedReference.Head == this && attachedReference.Start > num2) attachedReference.StartWith(this, attachedReference.Start + num); if (attachedReference.Tail == this && attachedReference.End > num2) attachedReference.EndWith(this, attachedReference.End + num); } } if (newElement.NodeType == NodeType.Document || newElement.Contains(this)) throw new DomException(DomError.HierarchyRequest); NodeList nodeList = new NodeList(); int num3 = _children.Index(referenceElement); if (num3 == -1) num3 = _children.Length; if (newElement._type == NodeType.DocumentFragment) { int num4 = num3; int i = num3; while (newElement.HasChildNodes) { Node node = newElement.ChildNodes[0]; newElement.RemoveChild(node, true); InsertNode(num4, node); num4++; } for (; i < num4; i++) { Node node2 = _children[i]; nodeList.Add(node2); NodeIsInserted(node2); } } else { nodeList.Add(newElement); InsertNode(num3, newElement); NodeIsInserted(newElement); } if (!suppressObservers) owner?.QueueMutation(MutationRecord.ChildList(this, nodeList, null, (num3 > 0) ? _children[num3 - 1] : null, referenceElement)); return newElement; } internal void RemoveChild(Node node, bool suppressObservers) { Document owner = Owner; int num = _children.Index(node); if (owner != null) { foreach (Range attachedReference in owner.GetAttachedReferences<Range>()) { if (attachedReference.Head.IsInclusiveDescendantOf(node)) attachedReference.StartWith(this, num); if (attachedReference.Tail.IsInclusiveDescendantOf(node)) attachedReference.EndWith(this, num); if (attachedReference.Head == this && attachedReference.Start > num) attachedReference.StartWith(this, attachedReference.Start - 1); if (attachedReference.Tail == this && attachedReference.End > num) attachedReference.EndWith(this, attachedReference.End - 1); } } Node node2 = (num > 0) ? _children[num - 1] : null; if (!suppressObservers && owner != null) { NodeList removedNodes = new NodeList { node }; owner.QueueMutation(MutationRecord.ChildList(this, null, removedNodes, node2, node.NextSibling)); owner.AddTransientObserver(node); } RemoveNode(num, node); NodeIsRemoved(node, node2); } internal Node ReplaceChild(Node node, Node child, bool suppressObservers) { if (this.IsEndPoint() || node.IsHostIncludingInclusiveAncestor(this)) throw new DomException(DomError.HierarchyRequest); if (child.Parent != this) throw new DomException(DomError.NotFound); if (node.IsInsertable()) { Node nextSibling = child.NextSibling; Document owner = Owner; NodeList nodeList = new NodeList(); NodeList nodeList2 = new NodeList(); IDocument document = this as IDocument; if (document != null && IsChangeForbidden(node, document, child)) throw new DomException(DomError.HierarchyRequest); if (nextSibling == node) nextSibling = node.NextSibling; owner?.AdoptNode(node); RemoveChild(child, true); InsertBefore(node, nextSibling, true); nodeList2.Add(child); if (node._type == NodeType.DocumentFragment) nodeList.AddRange(node._children); else nodeList.Add(node); if (!suppressObservers) owner?.QueueMutation(MutationRecord.ChildList(this, nodeList, nodeList2, child.PreviousSibling, nextSibling)); return child; } throw new DomException(DomError.HierarchyRequest); } protected virtual void ReplacedAll() { } public abstract Node Clone(Document newOwner, bool deep); public void AppendText(string s) { TextNode textNode = LastChild as TextNode; if (textNode != null) textNode.Append(s); else AddNode(new TextNode(Owner, s)); } public void InsertText(int index, string s) { if (index > 0 && index <= _children.Length) { IText text = _children[index - 1] as IText; if (text != null) { text.Append(s); return; } } if (index >= 0 && index < _children.Length) { IText text2 = _children[index] as IText; if (text2 != null) { text2.Insert(0, s); return; } } InsertNode(index, new TextNode(Owner, s)); } public void InsertNode(int index, Node node) { node.Parent = this; _children.Insert(index, node); } public void AddNode(Node node) { node.Parent = this; _children.Add(node); } public void RemoveNode(int index, Node node) { node.Parent = null; _children.RemoveAt(index); } public void ToHtml(TextWriter writer, IMarkupFormatter formatter) { IElement parentElement = ParentElement; foreach (INode item in this.GetDescendantsAndSelf()) { IComment comment = item as IComment; if (comment != null) writer.Write(formatter.Comment(comment)); else { IProcessingInstruction processingInstruction = item as IProcessingInstruction; if (processingInstruction != null) writer.Write(formatter.Processing(processingInstruction)); else { ICharacterData characterData = item as ICharacterData; if (characterData != null) { INode parent = characterData.Parent; if (parent != null && parent.Flags.HasFlag(NodeFlags.LiteralText)) writer.Write(formatter.LiteralText(characterData)); else writer.Write(formatter.Text(characterData)); } else { IDocumentType documentType = item as IDocumentType; if (documentType != null) writer.Write(formatter.Doctype(documentType)); else { IElement element = item as IElement; if (element != null) { NodeFlags flags = element.Flags; bool flag = flags.HasFlag(NodeFlags.SelfClosing); writer.Write(formatter.OpenTag(element, flag)); if (!flag && flags.HasFlag(NodeFlags.LineTolerance)) { IText text = element.FirstChild as IText; if (text != null && text.Data.Has('\n', 0)) writer.Write('\n'); } (element as IHtmlTemplateElement)?.Content.ToHtml(writer, formatter); if (!item.HasChildNodes) writer.Write(formatter.CloseTag(element, flag)); } } } } } if (!item.HasChildNodes && item.NextSibling == null) { for (IElement element2 = item.ParentElement; element2 != parentElement; element2 = ((element2.NextSibling == null) ? element2.ParentElement : parentElement)) { writer.Write(formatter.CloseTag(element2, element2.Flags.HasFlag(NodeFlags.SelfClosing))); } } } } public INode AppendChild(INode child) { return this.PreInsert(child, null); } public INode InsertChild(int index, INode child) { Node child2 = (index < _children.Length) ? _children[index] : null; return this.PreInsert(child, child2); } public INode InsertBefore(INode newElement, [System.Runtime.CompilerServices.Nullable(2)] INode referenceElement) { return this.PreInsert(newElement, referenceElement); } public INode ReplaceChild(INode newChild, INode oldChild) { return ReplaceChild((Node)newChild, (Node)oldChild, false); } public INode RemoveChild(INode child) { return this.PreRemove(child); } public INode Clone(bool deep = true) { return Clone(Owner, deep); } public DocumentPositions CompareDocumentPosition(INode otherNode) { if (this == otherNode) return DocumentPositions.Same; if (Owner != otherNode.Owner) { DocumentPositions documentPositions = (otherNode.GetHashCode() > GetHashCode()) ? DocumentPositions.Following : DocumentPositions.Preceding; return DocumentPositions.Disconnected | DocumentPositions.ImplementationSpecific | documentPositions; } if (otherNode.IsAncestorOf(this)) return DocumentPositions.Preceding | DocumentPositions.Contains; if (otherNode.IsDescendantOf(this)) return DocumentPositions.Following | DocumentPositions.ContainedBy; if (otherNode.IsPreceding(this)) return DocumentPositions.Preceding; return DocumentPositions.Following; } public bool Contains(INode otherNode) { return this.IsInclusiveAncestorOf(otherNode); } public void Normalize() { for (int i = 0; i < _children.Length; i++) { TextNode textNode = _children[i] as TextNode; if (textNode != null) { int num = textNode.Length; if (num == 0) { RemoveChild(textNode, false); i--; } else { StringBuilder stringBuilder = StringBuilderPool.Obtain(); TextNode textNode2 = textNode; int num2 = i; Document owner = Owner; while ((textNode2 = (textNode2.NextSibling as TextNode)) != null) { stringBuilder.Append(textNode2.Data); num2++; foreach (Range attachedReference in owner.GetAttachedReferences<Range>()) { if (attachedReference.Head == textNode2) attachedReference.StartWith(textNode, num); if (attachedReference.Tail == textNode2) attachedReference.EndWith(textNode, num); if (attachedReference.Head == textNode2.Parent && attachedReference.Start == num2) attachedReference.StartWith(textNode, num); if (attachedReference.Tail == textNode2.Parent && attachedReference.End == num2) attachedReference.EndWith(textNode, num); } num += textNode2.Length; } textNode.Replace(textNode.Length, 0, stringBuilder.ToPool()); for (int num3 = num2; num3 > i; num3--) { RemoveChild(_children[num3], false); } } } else if (_children[i].HasChildNodes) { _children[i].Normalize(); } } } [System.Runtime.CompilerServices.NullableContext(2)] public string LookupNamespaceUri(string prefix) { if (string.IsNullOrEmpty(prefix)) prefix = null; return LocateNamespace(prefix); } [System.Runtime.CompilerServices.NullableContext(2)] public string LookupPrefix(string namespaceUri) { if (string.IsNullOrEmpty(namespaceUri)) return null; return LocatePrefix(namespaceUri); } [System.Runtime.CompilerServices.NullableContext(2)] public bool IsDefaultNamespace(string namespaceUri) { if (string.IsNullOrEmpty(namespaceUri)) namespaceUri = null; string other = LocateNamespace(null); return namespaceUri.Is(other); } [System.Runtime.CompilerServices.NullableContext(2)] public virtual bool Equals(INode otherNode) { if (BaseUri.Is(otherNode?.BaseUri) && NodeName.Is(otherNode?.NodeName)) { int length = ChildNodes.Length; int? nullable = otherNode?.ChildNodes.Length; if ((length == nullable.GetValueOrDefault()) & nullable.HasValue) { for (int i = 0; i < _children.Length; i++) { if (!_children[i].Equals(otherNode.ChildNodes[i])) return false; } return true; } } return false; } private static bool IsChangeForbidden(Node node, IDocument parent, Node child) { switch (node._type) { case NodeType.DocumentType: if (parent.Doctype == child) return child.IsPrecededByElement(); return true; case NodeType.Element: if (parent.DocumentElement == child) return child.IsFollowedByDoctype(); return true; case NodeType.DocumentFragment: { int elementCount = node.GetElementCount(); if (elementCount <= 1 && !node.HasTextNodes()) { if (elementCount == 1) { if (parent.DocumentElement == child) return child.IsFollowedByDoctype(); return true; } return false; } return true; } default: return false; } } protected static void GetPrefixAndLocalName(string qualifiedName, [System.Runtime.CompilerServices.Nullable(2)] ref string namespaceUri, [System.Runtime.CompilerServices.Nullable(2)] out string prefix, out string localName) { if (!qualifiedName.IsXmlName()) throw new DomException(DomError.InvalidCharacter); if (!qualifiedName.IsQualifiedName()) throw new DomException(DomError.Namespace); if (string.IsNullOrEmpty(namespaceUri)) namespaceUri = null; int num = qualifiedName.IndexOf(':'); if (num > 0) { prefix = qualifiedName.Substring(0, num); localName = qualifiedName.Substring(num + 1); } else { prefix = null; localName = qualifiedName; } if (IsNamespaceError(prefix, namespaceUri, qualifiedName)) throw new DomException(DomError.Namespace); } [System.Runtime.CompilerServices.NullableContext(2)] protected static bool IsNamespaceError(string prefix, string namespaceUri, [System.Runtime.CompilerServices.Nullable(1)] string qualifiedName) { if ((prefix == null || namespaceUri != null) && (!prefix.Is(NamespaceNames.XmlPrefix) || namespaceUri.Is(NamespaceNames.XmlUri)) && ((!qualifiedName.Is(NamespaceNames.XmlNsPrefix) && !prefix.Is(NamespaceNames.XmlNsPrefix)) || namespaceUri.Is(NamespaceNames.XmlNsUri))) { if (namespaceUri.Is(NamespaceNames.XmlNsUri)) { if (!qualifiedName.Is(NamespaceNames.XmlNsPrefix)) return !prefix.Is(NamespaceNames.XmlNsPrefix); return false; } return false; } return true; } [return: System.Runtime.CompilerServices.Nullable(2)] protected virtual string LocateNamespace(string prefix) { return _parent?.LocateNamespace(prefix); } [return: System.Runtime.CompilerServices.Nullable(2)] protected virtual string LocatePrefix(string namespaceUri) { return _parent?.LocatePrefix(namespaceUri); } protected virtual void NodeIsAdopted(Document oldDocument) { } protected virtual void NodeIsInserted(Node newNode) { newNode.OnParentChanged(); } protected virtual void NodeIsRemoved(Node removedNode, [System.Runtime.CompilerServices.Nullable(2)] Node oldPreviousSibling) { removedNode.OnParentChanged(); } protected virtual void OnParentChanged() { } protected void CloneNode(Node target, Document owner, bool deep) { target._baseUri = _baseUri; if (deep) { foreach (Node child in _children) { if (child != null) { Node node = child; Node node2 = node.Clone(owner, true); target.AddNode(node2); } } } } } }