private Parsed ParseTerm()

in AjaxMinDll/Css/CssParser.cs [2575:2814]


        private Parsed ParseTerm(bool wasEmpty)
        {
            Parsed parsed = Parsed.False;
            bool hasUnary = false;
            if (CurrentTokenType == TokenType.Character
                && (CurrentTokenText == "-" || CurrentTokenText == "+"))
            {
                if (wasEmpty)
                {
                    if (m_skippedSpace)
                    {
                        Append(' ');
                    }

                    wasEmpty = false;
                }

                AppendCurrent();
                NextToken();
                hasUnary = true;
            }

            switch (CurrentTokenType)
            {
                case TokenType.Hash:
                    if (hasUnary)
                    {
                        ReportError(0, CssErrorCode.HashAfterUnaryNotAllowed, CurrentTokenText);
                    }

                    if (wasEmpty)
                    {
                        Append(' ');
                        wasEmpty = false;
                    }
                    if (ParseHexcolor() == Parsed.False)
                    {
                        ReportError(0, CssErrorCode.ExpectedHexColor, CurrentTokenText);

                        // we expected the hash token to be a proper color -- but it's not.
                        // we threw an error -- go ahead and output the token as-is and keep going.
                        AppendCurrent();
                        SkipSpace();
                    }
                    parsed = Parsed.True;
                    break;

                case TokenType.String:
                case TokenType.Identifier:
                case TokenType.Uri:
                //case TokenType.RGB:
                case TokenType.UnicodeRange:
                    if (hasUnary)
                    {
                        ReportError(0, CssErrorCode.TokenAfterUnaryNotAllowed, CurrentTokenText);
                    }

                    // wasEmpty will be false if we DIDN'T find an operator
                    // as the last token. If we had an operator, then we can ignore
                    // any whitespace; but if we DIDN'T find an operator, then we
                    // will need to preserve a whitespace character to keep them 
                    // separated.
                    if (wasEmpty)
                    {
                        // if we had skipped any space, then add one now
                        if (m_skippedSpace)
                        {
                            Append(' ');
                        }

                        wasEmpty = false;
                    }

                    AppendCurrent();
                    SkipSpace();
                    parsed = Parsed.True;
                    break;

                case TokenType.Dimension:
                    ReportError(2, CssErrorCode.UnexpectedDimension, CurrentTokenText);
                    goto case TokenType.Number;

                case TokenType.Number:
                case TokenType.Percentage:
                case TokenType.AbsoluteLength:
                case TokenType.RelativeLength:
                case TokenType.Angle:
                case TokenType.Time:
                case TokenType.Frequency:
                case TokenType.Resolution:
                    if (wasEmpty)
                    {
                        Append(' ');
                        wasEmpty = false;
                    }

                    AppendCurrent();
                    SkipSpace();
                    parsed = Parsed.True;
                    break;

                case TokenType.ProgId:
                    if (wasEmpty)
                    {
                        Append(' ');
                        wasEmpty = false;
                    }
                    if (ParseProgId() == Parsed.False)
                    {
                        ReportError(0, CssErrorCode.ExpectedProgId, CurrentTokenText);
                    }
                    parsed = Parsed.True;
                    break;

                case TokenType.Function:
                    if (wasEmpty)
                    {
                        Append(' ');
                        wasEmpty = false;
                    }
                    if (ParseFunction() == Parsed.False)
                    {
                        ReportError(0, CssErrorCode.ExpectedFunction, CurrentTokenText);
                    }
                    parsed = Parsed.True;
                    break;

                case TokenType.Character:
                    if (CurrentTokenText == "(")
                    {
                        // the term starts with an opening paren.
                        // parse an expression followed by the close paren.
                        if (wasEmpty)
                        {
                            if (m_skippedSpace)
                            {
                                Append(' ');
                            }

                            wasEmpty = false;
                        }

                        AppendCurrent();
                        SkipSpace();

                        if (ParseExpr() == Parsed.False)
                        {
                            ReportError(0, CssErrorCode.ExpectedExpression, CurrentTokenText);
                        }

                        if (CurrentTokenType == TokenType.Character
                            && CurrentTokenText == ")")
                        {
                            AppendCurrent();
                            parsed = Parsed.True;

                            // the closing paren can only be followed IMMEDIATELY by the opening brace
                            // without any space if it's a repeat syntax.
                            m_skippedSpace = false;
                            NextRawToken();
                            if (CurrentTokenType == TokenType.Space)
                            {
                                m_skippedSpace = true;
                            }

                            // if the next token is an opening brace, then this might be
                            // a repeat operator
                            if (CurrentTokenType == TokenType.Character
                                && CurrentTokenText == "[")
                            {
                                AppendCurrent();
                                SkipSpace();

                                if (CurrentTokenType == TokenType.Number)
                                {
                                    AppendCurrent();
                                    SkipSpace();

                                    if (CurrentTokenType == TokenType.Character
                                        && CurrentTokenText == "]")
                                    {
                                        AppendCurrent();
                                        SkipSpace();
                                    }
                                    else
                                    {
                                        ReportError(0, CssErrorCode.ExpectedClosingBracket, CurrentTokenText);
                                        parsed = Parsed.False;
                                    }
                                }
                                else
                                {
                                    ReportError(0, CssErrorCode.ExpectedNumber, CurrentTokenText);
                                    parsed = Parsed.False;
                                }
                            }
                        }
                        else
                        {
                            ReportError(0, CssErrorCode.ExpectedClosingParenthesis, CurrentTokenText);
                        }
                    }
                    else if ( CurrentTokenText == "%")
                    {
                        // see if this is the start of a replacement token
                        UpdateIfReplacementToken();
                        if (CurrentTokenType == TokenType.ReplacementToken)
                        {
                            // it was -- output it and move along
                            if (wasEmpty)
                            {
                                Append(' ');
                                wasEmpty = false;
                            }

                            AppendCurrent();
                            SkipSpace();
                            parsed = Parsed.True;
                        }
                        else
                        {
                            // nope; just a percent. 
                            goto default;
                        }
                    }
                    else
                    {
                        goto default;
                    }
                    break;

                default:
                    if (hasUnary)
                    {
                        ReportError(0, CssErrorCode.UnexpectedToken, CurrentTokenText);
                    }
                    break;
            }
            return parsed;
        }