// consume exactly 1 partial-step INodeMatcher ConsumePartialStep() { CssToken t = GetNext(); switch (t.Type) { case CssTokenType.Name: return(new NameSelector(t.Text)); case CssTokenType.Class: return(AttributeSelector.ContainsClass(t.Text.Substring(1))); case CssTokenType.Id: return(AttributeSelector.IdIs(t.Text.Substring(1))); case CssTokenType.Square: { CssToken insideText = GetNext(); GetNext(); // throw away closing token return(ParseAttribute(insideText.Text)); } case CssTokenType.Pseudo: switch (t.Text) { case ":even": return(SiblingSelector.Even); case ":odd": return(SiblingSelector.Odd); case ":nth-child": _index += 3; return(ParseSibling(_tokens[_index - 2].Text)); case ":contains": _index += 3; return(new ContainsTextSelector(_tokens[_index - 2].Text)); default: _index += 3; return(ParseColon(t.Text)); } } --_index; // If didn't use it, we need to push it back onto the stream return(null); }