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); // http://www.w3.org/TR/2009/CR-css3-mediaqueries-20090915/ // media_query_list: : S* media_query [ ',' S* media_query]* // // Several Media Queries can be combined in a comma-separated list. // If one or more of the Media Queries in the comma-separated list is true, // the associated style sheet is applied, otherwise the associated style sheet // is ignored. Consider this example written in CSS: // @media screen and (color), projection and (color) { ... } while (!tokens.CurrentToken.IsDirectiveTerminator()) { if (!ParseMediaQuery(itemFactory, text, tokens)) { // Don't know what this is, but I need to eat it and keep looking for the terminator Children.AddUnknownAndAdvance(itemFactory, text, tokens, ParseErrorType.UnexpectedParseError); } } MediaBlock = itemFactory.CreateSpecific <StyleSheet>(this); MediaBlock.IsNestedBlock = true; if (!ParseBlock(MediaBlock, itemFactory, text, tokens)) { MediaBlock = null; } return(Children.Count > 0); }
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 ParseDefaultChild(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { if (Colon != null) { ParsePropertyValue(itemFactory, text, tokens); } else { // Not an error because the missing colon is the real error Children.AddUnknownAndAdvance(itemFactory, text, tokens); } }
/// <summary> /// Skip over a complete block of unknown content /// </summary> public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { // Save the opening token for this block OpenBlock = Children.AddCurrentAndAdvance(tokens, null); CssTokenType matchingEndType = GetMatchingTokenType(OpenBlock.TokenType); Debug.Assert(matchingEndType != CssTokenType.Unknown); // Search for the matching end of the block bool invalidBlock = false; while (!invalidBlock && tokens.CurrentToken.TokenType != matchingEndType && !tokens.CurrentToken.IsScopeBlocker()) { // Treat the contents of the block as property values so that units, functions, etc. get parsed ParseItem pi = PropertyValueHelpers.ParsePropertyValue(this, itemFactory, text, tokens); if (pi != null) { Children.Add(pi); } else { switch (tokens.CurrentToken.TokenType) { case CssTokenType.CloseCurlyBrace: case CssTokenType.CloseFunctionBrace: case CssTokenType.CloseSquareBracket: // Found a non-matching end brace/bracket, so stop parsing invalidBlock = true; break; default: Children.AddUnknownAndAdvance(itemFactory, text, tokens); break; } } } if (tokens.CurrentToken.TokenType == matchingEndType) { CloseBlock = Children.AddCurrentAndAdvance(tokens, null); } else { OpenBlock.AddParseError(ParseErrorType.CloseBraceMismatch, ParseErrorLocation.AfterItem); } return(Children.Count > 0); }
protected virtual void ParsePropertyValue(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { ParseItem item = PropertyValueHelpers.ParsePropertyValue(this, itemFactory, text, tokens); if (item != null) { Values.Add(item); Children.Add(item); } else { Children.AddUnknownAndAdvance(itemFactory, text, tokens, ParseErrorType.PropertyValueExpected); } }
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 ParseArgument(ItemFactory itemFactory, ITextProvider text, TokenStream tokens) { while (!tokens.CurrentToken.IsFunctionArgumentTerminator()) { ParseItem pi = PropertyValueHelpers.ParsePropertyValue(this, itemFactory, text, tokens); if (pi != null) { ArgumentItems.Add(pi); Children.Add(pi); } else { // An unknown item is not an error pi = Children.AddUnknownAndAdvance(itemFactory, text, tokens); ArgumentItems.Add(pi); } } }
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) { 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); }