internal void OnScriptState(string scriptType, NameToken nameToken) { string scriptQualifiedName = _cs.GetSubstringAt(nameToken.QualifiedName.Start, nameToken.QualifiedName.Length); string endScript = string.Concat("</", scriptQualifiedName); ITextRange range = FindEndOfBlock(endScript, simpleSearch: true); ScriptBlockFound?.Invoke(this, new HtmlParserBlockRangeEventArgs(range, scriptType)); }
internal void OnStyleState(NameToken nameToken) { string styleQualifiedName = _cs.GetSubstringAt(nameToken.QualifiedName.Start, nameToken.QualifiedName.Length); string endStyle = string.Concat("</", styleQualifiedName); // here is interesting and somewhat odd piece... <style> and <script> blocks are artifacts too. // However, they cannot be handled through preprocessor since they are regular markup elements. // Worse still, <script runat="server"> is ASP.NET artifact... But since they are really // markup elements, we'll have to deal with them here. var range = FindEndOfBlock(endStyle, simpleSearch: true); StyleBlockFound?.Invoke(this, new HtmlParserBlockRangeEventArgs(range, String.Empty)); }
public ElementNode(ElementNode parent, int openAngleBracketPosition, NameToken nameToken, int maxEnd) { Parent = parent; if (nameToken.HasColon) StartTag = new TagNodeWithPrefix(this, openAngleBracketPosition, nameToken, maxEnd); else StartTag = new TagNode(this, openAngleBracketPosition, nameToken, maxEnd); VirtualEnd = maxEnd; Properties = new PropertyDictionary(); }
public TagNode(ElementNode parent, int openAngleBracketPosition, NameToken nameToken, int maxEnd) { NameToken = nameToken; _name = nameToken.HasName() ? parent.GetText(nameToken.NameRange) : String.Empty; _start = openAngleBracketPosition; _end = maxEnd; IsClosed = false; IsShorthand = false; }
public override string ToString() { if (NameToken != null && ValueToken != null) { return(String.Format(CultureInfo.CurrentCulture, "{0} = {1}", NameToken.ToString(), ValueToken.ToString())); } else if (NameToken != null) { return(NameToken.ToString()); } else if (ValueToken != null) { return(ValueToken.ToString()); } return("?"); }
public void Shift(int offset) { if (NameToken != null) { NameToken.Shift(offset); } if (EqualsSign >= 0) { EqualsSign += offset; } if (ValueToken != null) { ValueToken.Shift(offset); } }
public void ShiftStartingFrom(int start, int offset) { if (NameToken != null && NameToken.Start >= start) { Debug.Assert(!(start > NameToken.Start && start < NameToken.End), "Can't shift when start position is in the middle of a token"); NameToken.Shift(offset); } if (EqualsSign >= start) { EqualsSign += offset; } if (ValueToken != null) { if (ValueToken.Start >= start) { var composite = ValueToken as CompositeAttributeValueToken; if (composite != null) { composite.ShiftStartingFrom(start, offset); } else if (ValueToken.Start >= start) { ValueToken.Shift(offset); } } else if (ValueToken.Contains(start)) { var expandable = ValueToken as IExpandableTextRange; if (expandable != null) { expandable.Expand(0, offset); } } } }
/// <summary>Begins element end tag processing. Called exclusively by tree builder. /// when it discovers </name sequence.</summary> internal void OpenEndTag(int position, NameToken nameToken, int maxEnd) { EndTag = new TagNode(this, position, nameToken, maxEnd); }
public TagNodeWithPrefix(ElementNode parent, int openAngleBracketPosition, NameToken nameToken, int maxEnd) : base(parent, openAngleBracketPosition, nameToken, maxEnd) { _prefix = nameToken.HasPrefix() ? parent.GetText(nameToken.PrefixRange) : String.Empty; }
public HtmlParserOpenTagEventArgs(int openAngleBracketPosition, NameToken nameToken, bool isDocType, bool isXmlPi) { NameToken = nameToken; OpenAngleBracketPosition = openAngleBracketPosition; IsDocType = isDocType; IsXmlPi = isXmlPi; }
public HtmlParserOpenTagEventArgs(int openAngleBracketPosition, NameToken nameToken) : this(openAngleBracketPosition, nameToken, false, false) { }
// Similar to GetNextToken but also handles namespaces // It is typically called when parser is entering start tag. // Note that we do not allow artifacts in names public NameToken GetNameToken(int tagEnd = Int32.MaxValue, bool artifactTag = false) { // < at the end of file or missing tag name if (_cs.IsEndOfStream() || _cs.IsAtString() || _cs.IsWhiteSpace() || _cs.CurrentChar == '=' || _cs.CurrentChar == '/') { return(null); } int start = _cs.Position; int colonPos = -1; // Technically namespace and name starts with ANSI letter or underscore. Subsequent characters // can include digits except if it is second character after leading underscore, i.e. _2 is illegal // and also all underscores are illegal. However, we'll leave validation to the validator and will // only handle : and = as separators while (!_cs.IsEndOfStream() && _cs.Position < tagEnd && !_cs.IsWhiteSpace() && _cs.CurrentChar != '=' && _cs.CurrentChar != '/') { if (!artifactTag && _cs.IsAtTagDelimiter()) { break; } if (colonPos < 0 && _cs.CurrentChar == ':') { colonPos = _cs.Position; } _cs.MoveToNextChar(); } bool hasPrefix = colonPos > start; bool hasName = false; int nameStart = -1; int nameEnd = -1; if (hasPrefix || colonPos >= 0) { hasName = _cs.Position > colonPos + 1; if (hasName) { nameStart = colonPos + 1; nameEnd = _cs.Position; } } else { hasName = _cs.Position > start; if (hasName) { nameStart = start; nameEnd = _cs.Position; } } if (!hasPrefix && colonPos < 0 && !hasName) { return(null); } if (hasPrefix || colonPos >= 0) { return(NameToken.Create(start, colonPos - start, colonPos, nameStart, nameEnd - nameStart)); } else { return(NameToken.Create(nameStart, nameEnd - nameStart)); } }