AngleSharp by AngleSharp

<PackageReference Include="AngleSharp" Version="0.9.8" />

 CssValueBuilder

sealed class CssValueBuilder
The class that is responsible for book-keeping information about the current CSS value that is been build.
using AngleSharp.Dom.Css; using AngleSharp.Extensions; using System.Collections.Generic; namespace AngleSharp.Parser.Css { internal sealed class CssValueBuilder { private readonly List<CssToken> _values; private CssToken _buffer; private bool _valid; private bool _important; private int _open; public bool IsReady { get { if (_open == 0) return _values.Count > 0; return false; } } public bool IsValid { get { if (_valid) return IsReady; return false; } } public bool IsImportant => _important; public CssValueBuilder() { _values = new List<CssToken>(); Reset(); } public CssValue GetResult() { return new CssValue(_values); } public void Apply(CssToken token) { switch (token.Type) { case CssTokenType.Comment: break; case CssTokenType.RoundBracketOpen: _open++; Add(token); break; case CssTokenType.Function: Add(token); break; case CssTokenType.Ident: _important = CheckImportant(token); break; case CssTokenType.RoundBracketClose: _open--; Add(token); break; case CssTokenType.Whitespace: if (_values.Count > 0 && !IsSlash(_values[_values.Count - 1])) _buffer = token; break; case CssTokenType.String: case CssTokenType.Url: case CssTokenType.Color: case CssTokenType.Number: case CssTokenType.Percentage: case CssTokenType.Dimension: case CssTokenType.Delim: case CssTokenType.Comma: Add(token); break; default: _valid = false; Add(token); break; } } public CssValueBuilder Reset() { _open = 0; _valid = true; _buffer = null; _important = false; _values.Clear(); return this; } private bool CheckImportant(CssToken token) { if (_values.Count != 0 && token.Data == Keywords.Important && IsExclamationMark(_values[_values.Count - 1])) { do { _values.RemoveAt(_values.Count - 1); } while (_values.Count > 0 && _values[_values.Count - 1].Type == CssTokenType.Whitespace); return true; } Add(token); return _important; } private void Add(CssToken token) { if (_buffer != null && !IsCommaOrSlash(token)) _values.Add(_buffer); else if (_values.Count != 0 && !IsComma(token) && IsComma(_values[_values.Count - 1])) { _values.Add(CssToken.Whitespace); } _buffer = null; if (_important) _valid = false; _values.Add(token); } private static bool IsCommaOrSlash(CssToken token) { if (!IsComma(token)) return IsSlash(token); return true; } private static bool IsComma(CssToken token) { return token.Type == CssTokenType.Comma; } private static bool IsExclamationMark(CssToken token) { if (token.Type == CssTokenType.Delim) return token.Data.Has('!', 0); return false; } private static bool IsSlash(CssToken token) { if (token.Type == CssTokenType.Delim) return token.Data.Has('/', 0); return false; } } }