ICondition ExtractCondition(ref CssToken token) { var condition = default(ICondition); if (token.Type == CssTokenType.RoundBracketOpen) { token = _tokenizer.Get(); condition = CreateCondition(ref token); if (condition != null) condition = new GroupCondition(condition); else if (token.Type == CssTokenType.Ident) condition = DeclarationCondition(ref token); if (token.Type == CssTokenType.RoundBracketClose) token = _tokenizer.Get(); } else if (token.Data.Equals(Keywords.Not, StringComparison.OrdinalIgnoreCase)) { token = _tokenizer.Get(); condition = ExtractCondition(ref token); if (condition != null) condition = new NotCondition(condition); } return condition; }
static CssMatchToken() { include = new CssMatchToken { _type = CssTokenType.IncludeMatch }; dash = new CssMatchToken { _type = CssTokenType.DashMatch }; prefix = new CssMatchToken { _type = CssTokenType.PrefixMatch }; substring = new CssMatchToken { _type = CssTokenType.SubstringMatch }; suffix = new CssMatchToken { _type = CssTokenType.SuffixMatch }; not = new CssMatchToken { _type = CssTokenType.NotMatch }; }
public override CssRule Create(CssToken current) { var token = _tokenizer.Get(); var rule = new CssFontFaceRule(_parser); if (token.Type != CssTokenType.CurlyBracketOpen) return SkipDeclarations(token); FillFontFaceDeclarations(rule); return rule; }
public override CssRule Create(CssToken current) { var token = _tokenizer.Get(); var rule = new CssSupportsRule(_parser); rule.Condition = CreateCondition(ref token); if (token.Type != CssTokenType.CurlyBracketOpen) return SkipDeclarations(token); FillRules(rule); return rule; }
public override CssRule Create(CssToken current) { var token = _tokenizer.Get(); var rule = new CssDocumentRule(_parser); var functions = CreateFunctions(ref token); rule.Conditions.AddRange(functions); if (token.Type != CssTokenType.CurlyBracketOpen) return SkipDeclarations(token); FillRules(rule); return rule; }
/// <summary> /// Called when the document functions have to been found. /// </summary> public List<IDocumentFunction> CreateFunctions(ref CssToken token) { var list = new List<IDocumentFunction>(); do { var function = token.ToDocumentFunction(); if (function == null) break; list.Add(function); token = _tokenizer.Get(); } while (token.Type == CssTokenType.Comma); return list; }
ICondition DeclarationCondition(ref CssToken token) { var name = token.Data; var property = Factory.Properties.Create(name); if (property == null) property = new CssUnknownProperty(name); token = _tokenizer.Get(); if (token.Type == CssTokenType.Colon) { var important = false; var result = CreateValue(ref token, out important); property.IsImportant = important; if (result != null) return new DeclarationCondition(property, result); } return null; }
/// <summary> /// Called before any token in the value regime had been seen. /// </summary> public ICondition CreateCondition(ref CssToken token) { var condition = ExtractCondition(ref token); if (condition != null) { if (token.Data.Equals(Keywords.And, StringComparison.OrdinalIgnoreCase)) { token = _tokenizer.Get(); var conditions = MultipleConditions(condition, Keywords.And, ref token); return new AndCondition(conditions); } else if (token.Data.Equals(Keywords.Or, StringComparison.OrdinalIgnoreCase)) { token = _tokenizer.Get(); var conditions = MultipleConditions(condition, Keywords.Or, ref token); return new OrCondition(conditions); } } return condition; }
List<ICondition> MultipleConditions(ICondition condition, String connector, ref CssToken token) { var list = new List<ICondition>(); list.Add(condition); while (token.Type != CssTokenType.Eof) { condition = ExtractCondition(ref token); if (condition == null) break; list.Add(condition); if (!token.Data.Equals(connector, StringComparison.OrdinalIgnoreCase)) break; token = _tokenizer.Get(); } return list; }
/// <summary> /// 4.4.1. Data state /// </summary> CssToken Data(Char current) { switch (current) { case Specification.LF: case Specification.CR: case Specification.TAB: case Specification.SPACE: do { current = src.Next; }while (Specification.IsSpaceCharacter(current)); src.Back(); return(CssSpecialCharacter.Whitespace); case Specification.DQ: return(StringDQ(src.Next)); case Specification.NUM: return(HashStart(src.Next)); case Specification.DOLLAR: current = src.Next; if (current == Specification.EQ) { return(CssMatchToken.Suffix); } return(CssToken.Delim(src.Previous)); case Specification.SQ: return(StringSQ(src.Next)); case '(': return(CssBracketToken.OpenRound); case ')': return(CssBracketToken.CloseRound); case Specification.ASTERISK: current = src.Next; if (current == Specification.EQ) { return(CssMatchToken.Substring); } return(CssToken.Delim(src.Previous)); case Specification.PLUS: { var c1 = src.Next; if (c1 == Specification.EOF) { src.Back(); } else { var c2 = src.Next; src.Back(2); if (Specification.IsDigit(c1) || (c1 == Specification.FS && Specification.IsDigit(c2))) { return(NumberStart(current)); } } return(CssToken.Delim(current)); } case Specification.COMMA: return(CssSpecialCharacter.Comma); case Specification.FS: { var c = src.Next; if (Specification.IsDigit(c)) { return(NumberStart(src.Previous)); } return(CssToken.Delim(src.Previous)); } case Specification.DASH: { var c1 = src.Next; if (c1 == Specification.EOF) { src.Back(); } else { var c2 = src.Next; src.Back(2); if (Specification.IsDigit(c1) || (c1 == Specification.FS && Specification.IsDigit(c2))) { return(NumberStart(current)); } else if (Specification.IsNameStart(c1)) { return(IdentStart(current)); } else if (c1 == Specification.RSOLIDUS && !Specification.IsLineBreak(c2) && c2 != Specification.EOF) { return(IdentStart(current)); } else if (c1 == Specification.DASH && c2 == Specification.GT) { src.Advance(2); return(CssCommentToken.Close); } } return(CssToken.Delim(current)); } case Specification.SOLIDUS: current = src.Next; if (current == Specification.ASTERISK) { return(Comment(src.Next)); } return(CssToken.Delim(src.Previous)); case Specification.RSOLIDUS: current = src.Next; if (Specification.IsLineBreak(current) || current == Specification.EOF) { RaiseErrorOccurred(current == Specification.EOF ? ErrorCode.EOF : ErrorCode.LineBreakUnexpected); return(CssToken.Delim(src.Previous)); } return(IdentStart(src.Previous)); case Specification.COL: return(CssSpecialCharacter.Colon); case Specification.SC: return(CssSpecialCharacter.Semicolon); case Specification.LT: current = src.Next; if (current == Specification.EM) { current = src.Next; if (current == Specification.DASH) { current = src.Next; if (current == Specification.DASH) { return(CssCommentToken.Open); } current = src.Previous; } current = src.Previous; } return(CssToken.Delim(src.Previous)); case Specification.AT: return(AtKeywordStart(src.Next)); case '[': return(CssBracketToken.OpenSquare); case ']': return(CssBracketToken.CloseSquare); case Specification.CA: current = src.Next; if (current == Specification.EQ) { return(CssMatchToken.Prefix); } return(CssToken.Delim(src.Previous)); case '{': return(CssBracketToken.OpenCurly); case '}': return(CssBracketToken.CloseCurly); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return(NumberStart(current)); case 'U': case 'u': current = src.Next; if (current == Specification.PLUS) { current = src.Next; if (Specification.IsHex(current) || current == Specification.QM) { return(UnicodeRange(current)); } current = src.Previous; } return(IdentStart(src.Previous)); case Specification.PIPE: current = src.Next; if (current == Specification.EQ) { return(CssMatchToken.Dash); } else if (current == Specification.PIPE) { return(CssToken.Column); } return(CssToken.Delim(src.Previous)); case Specification.TILDE: current = src.Next; if (current == Specification.EQ) { return(CssMatchToken.Include); } return(CssToken.Delim(src.Previous)); case Specification.EOF: return(null); case Specification.EM: current = src.Next; if (current == Specification.EQ) { return(CssMatchToken.Not); } return(CssToken.Delim(src.Previous)); default: if (Specification.IsNameStart(current)) { return(IdentStart(current)); } return(CssToken.Delim(current)); } }
/// <summary> /// 4.4.23. Unicode-range State /// </summary> CssToken UnicodeRange(Char current) { for (int i = 0; i < 6; i++) { if (!Specification.IsHex(current)) { break; } stringBuffer.Append(current); current = src.Next; } if (stringBuffer.Length != 6) { for (int i = 0; i < 6 - stringBuffer.Length; i++) { if (current != Specification.QM) { current = src.Previous; break; } stringBuffer.Append(current); current = src.Next; } var range = FlushBuffer(); var start = range.Replace(Specification.QM, '0'); var end = range.Replace(Specification.QM, 'F'); return(CssToken.Range(start, end)); } else if (current == Specification.DASH) { current = src.Next; if (Specification.IsHex(current)) { var start = stringBuffer.ToString(); stringBuffer.Clear(); for (int i = 0; i < 6; i++) { if (!Specification.IsHex(current)) { current = src.Previous; break; } stringBuffer.Append(current); current = src.Next; } var end = FlushBuffer(); return(CssToken.Range(start, end)); } else { src.Back(2); return(CssToken.Range(FlushBuffer(), null)); } } else { src.Back(); return(CssToken.Range(FlushBuffer(), null)); } }