예제 #1
0
        /// <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);
        }
예제 #2
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);
            }
        }
        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);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// This helps the ColorParser class to figure out the values of each color argument.
        /// If the output argumentValue is float.NaN then the argument can still be valid, but
        /// its actualy value cannot be determined.
        /// </summary>
        internal virtual bool GetColorArgumentValue(int argumentIndex, bool looseParsing, out float argumentValue)
        {
            argumentValue = 0;

            FunctionArgument colorArgument = (argumentIndex >= 0 && argumentIndex < Arguments.Count)
                ? Arguments[argumentIndex] as FunctionArgument
                : null;

            // Make sure the argument has the right number of children

            if (colorArgument == null ||
                colorArgument.ArgumentItems.Count == 0 ||
                (!looseParsing && colorArgument.ArgumentItems.Count != 1))
            {
                return(false);
            }

            ParseItem colorNumber = colorArgument.ArgumentItems[0];
            UnitType  unitType    = PropertyValueHelpers.GetUnitType(colorNumber);

            if (argumentIndex > 3)
            {
                // No color function has more than four arguments
                return(false);
            }
            else if (argumentIndex == 3)
            {
                // It's the alpha value
                if (ColorFunction == ColorFunctionType.Rgba || ColorFunction == ColorFunctionType.Hsla)
                {
                    if (PropertyValueHelpers.IsValidNumber(colorNumber))
                    {
                        if (float.TryParse(colorNumber.Text, NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                        {
                            return(true);
                        }
                    }
                }
            }
            else if (ColorFunction == ColorFunctionType.Rgb || ColorFunction == ColorFunctionType.Rgba)
            {
                // Red, Green, and Blue are always a <percentage> or <integer>

                if (unitType == UnitType.Percentage)
                {
                    if (float.TryParse(colorNumber.Text.TrimEnd('%'), NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                    {
                        argumentValue /= 100.0f;
                        return(true);
                    }
                }
                else if (PropertyValueHelpers.IsValidInteger(colorNumber))
                {
                    if (int.TryParse(colorNumber.Text, out int intValue))
                    {
                        argumentValue = intValue / 255.0f;
                        return(true);
                    }
                }
            }
            else if (argumentIndex == 0)
            {
                // Hue is always a <number>

                if (PropertyValueHelpers.IsValidNumber(colorNumber))
                {
                    if (float.TryParse(colorNumber.Text, NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                    {
                        argumentValue /= 360.0f;
                        return(true);
                    }
                }
            }
            else
            {
                // Saturation and Lightness are always a percentage

                if (unitType == UnitType.Percentage)
                {
                    if (float.TryParse(colorNumber.Text.TrimEnd('%'), NumberStyles.Number, NumberFormatInfo.InvariantInfo, out argumentValue))
                    {
                        argumentValue /= 100.0f;
                        return(true);
                    }
                }
            }

            return(false);
        }