private static CssPseudoClass[] ParsePseudoClasses(CssStringStreamReader reader) { var classes = new List <CssPseudoClass>(); while (reader.CurrentChar == ':') { reader.Advance(); if (!reader.TryReadIdentifier(out var className)) { return(null); } if (CssFunctionalPseudoClass.TryConvertToFunctionalPseudoClassType(className, out var functionalClassType)) { if (!reader.Read('(') || !TryParseSelectorList(reader, out var functionalSelectors) || !reader.Read(')')) { return(null); } classes.Add(new CssFunctionalPseudoClass(functionalSelectors, functionalClassType)); continue; } if (CssUserActionPseudoClass.TryConvertToUserActionPseudoClassType(className, out var userActionClassType)) { classes.Add(new CssUserActionPseudoClass(userActionClassType)); continue; } if (CssStructuralPseudoClass.TryConvertToStructuralPseudoClassType(className, out var structuralPseudoClassType)) { if (!reader.Read('(') || !TryParseSelectorList(reader, out var structuralSelectors) || !reader.Read(')')) { structuralSelectors = new CssSelectorList(); } classes.Add(new CssStructuralPseudoClass(structuralSelectors, structuralPseudoClassType)); continue; } return(null); // unknown / unhandled pseudo class } return(classes.ToArray()); }
/// <summary> /// Tries to parse a collection of properties (name value pairs, e.g. 'fill:#000') of a style body /// </summary> public static bool TryParseStyleRuleBodyProperties(CssStringStreamReader reader, out Dictionary <string, CssStylePropertyValue> properties) { properties = new Dictionary <string, CssStylePropertyValue>(); reader.SkipWhitespaceAndComments(); var builder = new StringBuilder(); while (!reader.IsEndOfStream && reader.CurrentChar != '}') { if (!reader.TryReadIdentifier(out var name)) { return(false); } reader.SkipWhitespaceAndComments(); if (!reader.Read(':')) { return(false); } reader.SkipWhitespaceAndComments(); while (reader.CurrentChar != ';' && reader.CurrentChar != '}' && !reader.IsEndOfStream) { builder.Append(reader.CurrentChar); reader.Advance(); } properties[name] = new CssStylePropertyValue(builder.ToString()); builder.Clear(); if (reader.CurrentChar == ';') { reader.Read(';'); } reader.SkipWhitespaceAndComments(); } return(true); }
public static bool TryParseRules(CssStringStreamReader reader, out CssStyleRulesList rules) { rules = new CssStyleRulesList(); reader.SkipWhitespaceAndComments(); while (!reader.IsEndOfStream) { if (!TryParseSelectorList(reader, out var selectors) || !reader.SkipWhitespaceAndComments() || !reader.Read('{') || !TryParseStyleRuleBodyProperties(reader, out var properties) || !reader.SkipWhitespaceAndComments() || !reader.Read('}')) { return(false); } rules.Add(new CssStyleRule(selectors, properties)); reader.SkipWhitespaceAndComments(); } return(true); }