/// <summary> /// If this next work from the current point in the given string navigator appears to be a recognised pseudo class then this will return a result that /// will ensure that the current character is identified as a selector-or-property-name content rather than a property-name-value-separator colon (the /// string navigator passed here will be for the position directly after the colon, which is what is currently being negotiated). Any whitespace at /// the current position will be moved over when looking for pseudo class content. If the content does not appear to be for a pseudo class then null /// will be returned and the caller may continue with whatever logic it wants to. /// </summary> private CharacterProcessorResult GetPseudoClassHandlingProcessResultIfApplicable(IWalkThroughStrings stringNavigatorAtStartOfPotentialPseudoClass) { if (stringNavigatorAtStartOfPotentialPseudoClass == null) { throw new ArgumentNullException("stringNavigator"); } // If the first character of the possible-psuedo-class content is a ":" then it means that we've encountered a "::" (since the first ":" triggered // this method to be called with the content after it) and that means that it's definitely a psuedo class and not a property name / value pair. As // such we'll return a process that swallows this second ":" and then processes the next content as selector-or-style-content (and not as property // name content) if (stringNavigatorAtStartOfPotentialPseudoClass.CurrentCharacter == ':') { var contentProcessor = GetSelectorOrStyleCharacterProcessor(); return(new CharacterProcessorResult( CharacterCategorisationOptions.SelectorOrStyleProperty, new SkipCharactersSegment(CharacterCategorisationOptions.SelectorOrStyleProperty, 1, GetSelectorOrStyleCharacterProcessor()) )); } // Skip over any whitespace to find the start of the next content var whiteSpaceCharactersToSkipOver = 0; while (true) { var character = stringNavigatorAtStartOfPotentialPseudoClass.CurrentCharacter; if ((character == null) || !char.IsWhiteSpace(character.Value)) { break; } stringNavigatorAtStartOfPotentialPseudoClass = stringNavigatorAtStartOfPotentialPseudoClass.Next; whiteSpaceCharactersToSkipOver++; } // Determine whether that content (if there is any) matches any of the pseudo classes if (PseudoClasses.Any(c => stringNavigatorAtStartOfPotentialPseudoClass.DoesCurrentContentMatch(c))) { IProcessCharacters contentProcessor = GetSelectorOrStyleCharacterProcessor(); if (whiteSpaceCharactersToSkipOver > 0) { contentProcessor = new SkipCharactersSegment(CharacterCategorisationOptions.Whitespace, whiteSpaceCharactersToSkipOver, contentProcessor); } return(new CharacterProcessorResult( CharacterCategorisationOptions.SelectorOrStyleProperty, contentProcessor )); } return(null); }