protected virtual void ParseName(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.Function && tokens.CurrentToken.Start == Colon.AfterEnd) { if (TextRange.CompareDecoded(tokens.CurrentToken.Start, tokens.CurrentToken.Length, text, "not(", ignoreCase: true)) { Function = itemFactory.CreateSpecific <PseudoFunctionNot>(this); } else if (TextRange.CompareDecoded(tokens.CurrentToken.Start, tokens.CurrentToken.Length, text, "matches(", ignoreCase: true)) { Function = itemFactory.CreateSpecific <PseudoFunctionMatches>(this); } else { Function = itemFactory.CreateSpecific <Function>(this); } Function.Parse(itemFactory, text, tokens); // Function name should be colorizer as pseudo-class Function.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PseudoClass); Function.FunctionName.Context = Function.Context; Children.Add(Function); } else { Children.AddParseError(ParseErrorType.PseudoClassNameMissing); } }
protected virtual bool ParseArguments(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.IsFunctionTerminator()) { // There could be functions without arguments (like "filter: mask();") return(false); } while (!tokens.CurrentToken.IsFunctionTerminator()) { ParseItem fa = CreateArgumentObject(this, itemFactory, Arguments.Count); if (fa.Parse(itemFactory, text, tokens)) { fa.Context = GetArgumentContext(Arguments.Count); Children.Add(fa); Arguments.Add(fa); } else { // Don't know what this is Children.AddUnknownAndAdvance(itemFactory, text, tokens, ParseErrorType.UnexpectedToken); } } FunctionArgument lastArgument = (Arguments.Count > 0) ? Arguments[Arguments.Count - 1] as FunctionArgument : null; if (lastArgument != null && lastArgument.Comma != null && lastArgument == Children[Children.Count - 1]) { Children.AddParseError(ParseErrorType.FunctionArgumentMissing); } return(true); }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { ParseAtAndKeyword(itemFactory, text, tokens); ParseAfterName(itemFactory, text, tokens); bool foundEnd = false; while (!tokens.CurrentToken.IsBlockTerminator()) { CssTokenType tokenType = tokens.CurrentToken.TokenType; if (tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace) { BlockItem block = NewBlock(); if (block == null) { break; } else if (block.Parse(itemFactory, text, tokens)) { foundEnd = true; Block = block; Children.Add(block); } else { foundEnd = true; Children.AddUnknownAndAdvance(itemFactory, text, tokens); } } else if (!ParseNextChild(itemFactory, text, tokens)) { TokenItem item = Children.AddUnknownAndAdvance(itemFactory, text, tokens) as TokenItem; if (item != null && item.TokenType == CssTokenType.Semicolon) { Debug.Assert(Semicolon == null); Semicolon = item; } } if (tokenType == CssTokenType.Semicolon) { foundEnd = true; break; } else if (tokenType == CssTokenType.OpenCurlyBrace) { break; } } if (!foundEnd && !AllowUnclosed) { Children.AddParseError(ParseErrorType.AtDirectiveSemicolonMissing); } return(Children.Count > 0); }
protected virtual void ParseName(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (IsNameToken(tokens.CurrentToken) && tokens.CurrentToken.Start == Colon.AfterEnd) { PseudoClass = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.PseudoClass); } else { Children.AddParseError(ParseErrorType.PseudoClassNameMissing); } }
protected virtual void ParseFeatureName(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { MediaFeature = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.MediaFeatureName); } else { Children.AddParseError(ParseErrorType.PropertyNameMissing); } }
protected virtual ParseItem ParseName(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { return(Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.AtDirectiveKeyword)); } else { Children.AddParseError(ParseErrorType.KeyFrameBlockNameMissing); return(null); } }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.Comma) { Comma = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.Default); } if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { if (TextRange.CompareDecoded(tokens.CurrentToken.Start, tokens.CurrentToken.Length, text, "only", ignoreCase: true) || TextRange.CompareDecoded(tokens.CurrentToken.Start, tokens.CurrentToken.Length, text, "not", ignoreCase: true)) { Operation = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.MediaQueryOperation); } } if (tokens.CurrentToken.TokenType == CssTokenType.Identifier && !IsMediaExpressionStart(text, tokens.CurrentToken)) { MediaType = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.MediaType); } else if (tokens.CurrentToken.TokenType != CssTokenType.OpenFunctionBrace) { Children.AddParseError(ParseErrorType.MediaTypeMissing); } while (!tokens.CurrentToken.IsDirectiveTerminator() && tokens.CurrentToken.TokenType != CssTokenType.Comma) { if (IsMediaExpressionStart(text, tokens.CurrentToken)) { MediaExpression mx = itemFactory.CreateSpecific <MediaExpression>(this); if (mx.Parse(itemFactory, text, tokens)) { Expressions.Add(mx); Children.Add(mx); } else { Children.AddUnknownAndAdvance(itemFactory, text, tokens, ParseErrorType.MediaExpressionExpected); } } else { Children.AddUnknownAndAdvance(itemFactory, text, tokens, ParseErrorType.UnexpectedMediaQueryToken); } } return(Children.Count > 0); }
protected virtual void ParseName(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.Function && tokens.CurrentToken.Start == DoubleColon.AfterEnd) { Function = itemFactory.CreateSpecific <Function>(this); Function.Parse(itemFactory, text, tokens); Function.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.PseudoElement); Children.Add(Function); } else { Children.AddParseError(ParseErrorType.PseudoElementNameMissing); } }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { while (true) { if (tokens.CurrentToken.TokenType != CssTokenType.Comma && tokens.CurrentToken.IsSelectorGroupTerminator()) { break; } Selector selector = itemFactory.CreateSpecific <Selector>(this); if (!selector.Parse(itemFactory, text, tokens)) { break; } Selectors.Add(selector); Children.Add(selector); } Selector lastSelector = (Selectors.Count > 0) ? Selectors[Selectors.Count - 1] : null; if (tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace) { if (Children.Count == 0) { Children.AddParseError(ParseErrorType.SelectorBeforeRuleBlockMissing); } if (lastSelector != null && lastSelector.Comma != null) { Children.AddParseError(ParseErrorType.SelectorAfterCommaMissing); } RuleBlock ruleBlock = itemFactory.CreateSpecific <RuleBlock>(this); if (ruleBlock.Parse(itemFactory, text, tokens)) { Block = ruleBlock; Children.Add(ruleBlock); } } else if (lastSelector != null) { AddParseError(ParseErrorType.OpenCurlyBraceMissingForRule, ParseErrorLocation.AfterItem); } return(Children.Count > 0); }
protected override void ParseArgument(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { SimpleSelector simpleSelector = itemFactory.CreateSpecific <SimpleSelector>(this); if (simpleSelector.ParseInFunction(itemFactory, text, tokens)) { Selector = simpleSelector; ArgumentItems.Add(Selector); Children.Add(Selector); } if (tokens.CurrentToken.TokenType != CssTokenType.Comma && tokens.CurrentToken.TokenType != CssTokenType.CloseFunctionBrace) { Children.AddParseError(ParseErrorType.FunctionArgumentCommaMissing); } }
/// <summary> /// Helper function for derived classes to parse their block /// </summary> protected bool ParseBlock(BlockItem block, ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace) { if (block.Parse(itemFactory, text, tokens)) { Children.Add(block); return(true); } } else { Children.AddParseError(ParseErrorType.OpenCurlyBraceMissing); } return(false); }
protected virtual void ParseBang(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (Bang == null) { Bang = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.Important); if (TextRange.CompareDecoded(tokens.CurrentToken.Start, tokens.CurrentToken.Length, text, "important", ignoreCase: true)) { Important = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.Important); } else { Children.AddParseError(ParseErrorType.ImportantMissing); } } else { Children.AddUnknownAndAdvance(itemFactory, text, tokens, ParseErrorType.UnexpectedBangInProperty); } }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { // @charset "Shift_JIS"; ParseAtAndKeyword(itemFactory, text, tokens); // In case semicolon is missing we don't want to continue parsing up // until next semicolon (although technically it is correct per W3C // @ directive definition. If we've seen charset spec we'll stop at the next // token that is not typically part of the @charset syntax if (tokens.CurrentToken.IsString()) { CharacterSet = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.CharsetName); } else { Children.AddParseError(ParseErrorType.EncodingMissing); } CheckSemicolon(tokens); return(Children.Count > 0); }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { ParseAtAndKeyword(itemFactory, text, tokens); if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { Namespace = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.ItemNamespace); } if (tokens.CurrentToken.IsString()) { String = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.String); } else if (tokens.CurrentToken.TokenType == CssTokenType.Url) { Url = new UrlItem(); if (Url.Parse(itemFactory, text, tokens)) { Url.Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.UrlString); Children.Add(Url); } else { Url = null; } } if (String == null && Url == null) { Children.AddParseError(ParseErrorType.UrlNamespaceMissing); } CheckSemicolon(tokens); return(Children.Count > 0); }
protected virtual void ParseUrl(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.IsString()) { FileNames.Add(Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.ImportUrl)); } else if (tokens.CurrentToken.TokenType == CssTokenType.Url) { UrlItem url = new UrlItem { Context = CssClassifierContextCache.FromTypeEnum(CssClassifierContextType.ImportUrl) }; if (url.Parse(itemFactory, text, tokens)) { FileNames.Add(url); Children.Add(url); } } else { Children.AddParseError(ParseErrorType.UrlImportMissing); } }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { ParseAtAndKeyword(itemFactory, text, tokens); // page : PAGE_SYM S* IDENT? pseudo_page? S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S* // pseudo_page : ':' [ "left" | "right" | "first" ] if (tokens.CurrentToken.TokenType == CssTokenType.Identifier) { Identifier = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.PseudoPageType); } if (tokens.CurrentToken.TokenType == CssTokenType.Colon) { Colon = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.PseudoPageType); if (tokens.CurrentToken.TokenType == CssTokenType.Identifier && tokens.CurrentToken.Start == Colon.AfterEnd) { PseudoPage = Children.AddCurrentAndAdvance(tokens, CssClassifierContextType.PseudoPageType); } else { Children.AddParseError(ParseErrorType.PseudoPageIdentifierMissing); } } PageDirectiveBlock = new PageDirectiveBlock(); if (!ParseBlock(PageDirectiveBlock, itemFactory, text, tokens)) { PageDirectiveBlock = null; } return(Children.Count > 0); }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { bool allowSelector = true; bool addedUnknownToken = false; while (tokens.CurrentToken.TokenType != CssTokenType.OpenCurlyBrace && tokens.CurrentToken.TokenType != CssTokenType.CloseCurlyBrace && !tokens.CurrentToken.IsScopeBlocker()) { KeyFramesSelector kfs = allowSelector ? new KeyFramesSelector() : null; if (kfs != null && kfs.Parse(itemFactory, text, tokens)) { Selectors.Add(kfs); Children.Add(kfs); allowSelector = (kfs.Comma != null); addedUnknownToken = false; } else { // Skip unknown stuff (only the first unknown token in a row will be an error) if (addedUnknownToken) { Children.AddUnknownAndAdvance(itemFactory, text, tokens); } else { Children.AddUnknownAndAdvance(itemFactory, text, tokens, allowSelector ? ParseErrorType.KeyFramesSelectorExpected : ParseErrorType.UnexpectedToken); allowSelector = true; addedUnknownToken = true; } } } KeyFramesSelector lastSelector = (Selectors.Count > 0) ? Selectors[Selectors.Count - 1] : null; if (tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace) { if (Children.Count == 0) { Children.AddParseError(ParseErrorType.SelectorBeforeRuleBlockMissing); } if (lastSelector != null && lastSelector.Comma != null && !addedUnknownToken) { Children.AddParseError(ParseErrorType.SelectorAfterCommaMissing); } RuleBlock rb = itemFactory.CreateSpecific <RuleBlock>(this); if (rb.Parse(itemFactory, text, tokens)) { RuleBlock = rb; Children.Add(rb); } } else if (lastSelector != null) { AddParseError(ParseErrorType.OpenCurlyBraceMissingForRule, ParseErrorLocation.AfterItem); } return(Children.Count > 0); }
public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (tokens.CurrentToken.TokenType == CssTokenType.At) { ParseAtAndKeyword(itemFactory, text, tokens); // all lowercase per W3C BNF if (Keyword == null) { Children.AddParseError(ParseErrorType.AtDirectiveNameMissing); } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "top-left-corner", ignoreCase: false)) { DirectiveType = MarginDirectiveType.TopLeftCorner; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "top-left", ignoreCase: false)) { DirectiveType = MarginDirectiveType.TopLeft; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "top-center", ignoreCase: false)) { DirectiveType = MarginDirectiveType.TopCenter; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "top-right", ignoreCase: false)) { DirectiveType = MarginDirectiveType.TopRight; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "top-right-corner", ignoreCase: false)) { DirectiveType = MarginDirectiveType.TopRightCorner; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "bottom-left-corner", ignoreCase: false)) { DirectiveType = MarginDirectiveType.BottomLeftCorner; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "bottom-left", ignoreCase: false)) { DirectiveType = MarginDirectiveType.BottomLeft; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "bottom-center", ignoreCase: false)) { DirectiveType = MarginDirectiveType.BottomCenter; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "bottom-right", ignoreCase: false)) { DirectiveType = MarginDirectiveType.BottomRight; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "bottom-right-corner", ignoreCase: false)) { DirectiveType = MarginDirectiveType.BottomRightCorner; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "left-top", ignoreCase: false)) { DirectiveType = MarginDirectiveType.LeftTop; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "left-middle", ignoreCase: false)) { DirectiveType = MarginDirectiveType.LeftMiddle; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "left-bottom", ignoreCase: false)) { DirectiveType = MarginDirectiveType.LeftBottom; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "right-top", ignoreCase: false)) { DirectiveType = MarginDirectiveType.RightTop; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "right-middle", ignoreCase: false)) { DirectiveType = MarginDirectiveType.RightMiddle; } else if (TextRange.CompareDecoded(Keyword.Start, Keyword.Length, text, "right-bottom", ignoreCase: false)) { DirectiveType = MarginDirectiveType.RightBottom; } else { DirectiveType = MarginDirectiveType.Unknown; } } RuleBlock = itemFactory.CreateSpecific <RuleBlock>(this); if (!ParseBlock(RuleBlock, itemFactory, text, tokens)) { RuleBlock = null; } return(Children.Count > 0); }