Microsoft.Html.Core.Tree.Nodes.ElementNode.GetPositionElement C# (CSharp) Method

GetPositionElement() public method

Determines position type and enclosing element node for a given position in the document text.
public GetPositionElement ( int position, ElementNode &element, AttributeNode &attribute ) : HtmlPositionType
position int Position in the document text
element ElementNode Element that contains position
attribute AttributeNode Attribute that contains position (may be null)
return HtmlPositionType
        public virtual HtmlPositionType GetPositionElement(int position, out ElementNode element, out AttributeNode attribute) {
            element = null;
            attribute = null;

            // If start tag is not closed, consider end position to be inside it
            // so user can continue getting attribute intellisense, like in <a href=|<a ...></a>
            if (StartTag.Contains(position) || (position == StartTag.End && !StartTag.IsClosed)) {
                // If position is right at the start, it is actually before the tag (in parent's content), 
                // as if when caret position is like this: <table>|<tr></tr><table>
                if (position == StartTag.Start) {
                    element = this.Parent;
                    return HtmlPositionType.InContent;
                }

                if (position >= QualifiedNameRange.Start && position <= StartTag.QualifiedNameRange.End) {
                    element = this;
                    return HtmlPositionType.ElementName;
                }

                element = this;

                for (int i = 0; i < Attributes.Count; i++) {
                    var attrNode = Attributes[i];
                    bool hasClosingQuote = false;

                    var valueToken = attrNode.ValueToken;
                    hasClosingQuote = (valueToken != null) && (valueToken.CloseQuote != '\0');

                    if (position == attrNode.End && hasClosingQuote)
                        break;

                    if (position > attrNode.End)
                        continue;

                    if (position < attrNode.Start)
                        break;

                    if (attrNode.Contains(position) || (position == attrNode.End && !hasClosingQuote)) {
                        attribute = attrNode;
                        return attrNode.GetPositionType(position);
                    }
                }

                return HtmlPositionType.InStartTag;
            }

            if (!this.Contains(position))
                return HtmlPositionType.Undefined;

            for (int i = 0; i < this.Children.Count; i++) {
                var child = Children[i];

                if (position < child.Start)
                    break;

                if (child.Contains(position))
                    return child.GetPositionElement(position, out element, out attribute);
            }

            element = this;

            // If position is right at the start, it is actually before the end tag, 
            // like when caret is between opening and closing tags: <table>|<table>
            if (EndTag != null) {
                if (position == EndTag.Start)
                    return HtmlPositionType.InContent;

                if (EndTag.Contains(position))
                    return HtmlPositionType.InEndTag;
            }

            if (this.IsScriptBlock())
                return HtmlPositionType.InScriptBlock;

            if (this.IsStyleBlock())
                return HtmlPositionType.InStyleBlock;

            return HtmlPositionType.InContent;
        }