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;
}