Exemplo n.º 1
0
        // Assigns to aValue iff it returns true.
        internal bool ParseVariant(ref nsCSSValue aValue,
                                    int32_t aVariantMask,
                                    int32_t[] aKeywordTable)
        {
            Debug.Assert(!(mHashlessColorQuirk && ((aVariantMask & VARIANT_COLOR) != 0)) ||
                       !((aVariantMask & VARIANT_NUMBER) != 0),
                       "can't distinguish colors from numbers");
              Debug.Assert(!(mHashlessColorQuirk && ((aVariantMask & VARIANT_COLOR) != 0)) ||
                       !(mUnitlessLengthQuirk && ((aVariantMask & VARIANT_LENGTH) != 0)),
                       "can't distinguish colors from lengths");
              Debug.Assert(!(mUnitlessLengthQuirk && ((aVariantMask & VARIANT_LENGTH) != 0)) ||
                       !((aVariantMask & VARIANT_NUMBER) != 0),
                       "can't distinguish lengths from numbers");
              Debug.Assert(!((aVariantMask & VARIANT_IDENTIFIER) != 0) ||
                            !((aVariantMask & VARIANT_IDENTIFIER_NO_INHERIT) != 0),
                            "must not set both VARIANT_IDENTIFIER and VARIANT_IDENTIFIER_NO_INHERIT");

              if (!GetToken(true)) {
            return false;
              }
              nsCSSToken tk = mToken;
              if (((aVariantMask & (VARIANT_AHK | VARIANT_NORMAL | VARIANT_NONE | VARIANT_ALL)) != 0) &&
              (nsCSSTokenType.Ident == tk.mType)) {
            nsCSSKeyword keyword = nsCSSKeywords.LookupKeyword(tk.mIdentStr);
            if (nsCSSKeyword.UNKNOWN < keyword) { // known keyword
              if ((aVariantMask & VARIANT_AUTO) != 0) {
                if (nsCSSKeyword.auto == keyword) {
                  aValue.SetAutoValue();
                  return true;
                }
              }
              if ((aVariantMask & VARIANT_INHERIT) != 0) {
                // XXX Should we check IsParsingCompoundProperty, or do all
                // callers handle it?  (Not all callers set it, though, since
                // they want the quirks that are disabled by setting it.)
                if (nsCSSKeyword.inherit == keyword) {
                  aValue.SetInheritValue();
                  return true;
                }
                else if (nsCSSKeyword._moz_initial == keyword ||
                         nsCSSKeyword.initial == keyword) { // anything that can inherit can also take an initial val.
                  aValue.SetInitialValue();
                  return true;
                }
              }
              if ((aVariantMask & VARIANT_NONE) != 0) {
                if (nsCSSKeyword.none == keyword) {
                  aValue.SetNoneValue();
                  return true;
                }
              }
              if ((aVariantMask & VARIANT_ALL) != 0) {
                if (nsCSSKeyword.all == keyword) {
                  aValue.SetAllValue();
                  return true;
                }
              }
              if ((aVariantMask & VARIANT_NORMAL) != 0) {
                if (nsCSSKeyword.normal == keyword) {
                  aValue.SetNormalValue();
                  return true;
                }
              }
              if ((aVariantMask & VARIANT_SYSFONT) != 0) {
                if (nsCSSKeyword._moz_use_system_font == keyword &&
                    !IsParsingCompoundProperty()) {
                  aValue.SetSystemFontValue();
                  return true;
                }
              }
              if ((aVariantMask & VARIANT_KEYWORD) != 0) {
                int32_t value = 0;
                if (nsCSSProps.FindKeyword(keyword, aKeywordTable, ref value)) {
                  aValue.SetIntValue(value, nsCSSUnit.Enumerated);
                  return true;
                }
              }
            }
              }
              // Check VARIANT_NUMBER and VARIANT_INTEGER before VARIANT_LENGTH or
              // VARIANT_ZERO_ANGLE.
              if (((aVariantMask & VARIANT_NUMBER) != 0) &&
              (nsCSSTokenType.Number == tk.mType)) {
            aValue.SetFloatValue(tk.mNumber, nsCSSUnit.Number);
            return true;
              }
              if (((aVariantMask & VARIANT_INTEGER) != 0) &&
              (nsCSSTokenType.Number == tk.mType) && tk.mIntegerValid) {
            aValue.SetIntValue(tk.mInteger, nsCSSUnit.Integer);
            return true;
              }
              if (((aVariantMask & (VARIANT_LENGTH | VARIANT_ANGLE |
                                VARIANT_FREQUENCY | VARIANT_TIME)) != 0 &&
               nsCSSTokenType.Dimension == tk.mType) ||
              ((aVariantMask & (VARIANT_LENGTH | VARIANT_ZERO_ANGLE)) != 0 &&
               nsCSSTokenType.Number == tk.mType &&
               tk.mNumber == 0.0f)) {
            if (((aVariantMask & VARIANT_POSITIVE_DIMENSION) != 0 &&
                 tk.mNumber <= 0.0) ||
                ((aVariantMask & VARIANT_NONNEGATIVE_DIMENSION) != 0 &&
                 tk.mNumber < 0.0)) {
                UngetToken();
                return false;
            }
            if (TranslateDimension(ref aValue, aVariantMask, tk.mNumber, tk.mIdentStr)) {
              return true;
            }
            // Put the token back; we didn't parse it, so we shouldn't consume it
            UngetToken();
            return false;
              }
              if (((aVariantMask & VARIANT_PERCENT) != 0) &&
              (nsCSSTokenType.Percentage == tk.mType)) {
            aValue.SetPercentValue(tk.mNumber);
            return true;
              }
              if (mUnitlessLengthQuirk) { // NONSTANDARD: Nav interprets unitless numbers as px
            if (((aVariantMask & VARIANT_LENGTH) != 0) &&
                (nsCSSTokenType.Number == tk.mType)) {
              aValue.SetFloatValue(tk.mNumber, nsCSSUnit.Pixel);
              return true;
            }
              }

              if (IsSVGMode() && !IsParsingCompoundProperty()) {
            // STANDARD: SVG Spec states that lengths and coordinates can be unitless
            // in which case they default to user-units (1 px = 1 user unit)
            if (((aVariantMask & VARIANT_LENGTH) != 0) &&
                (nsCSSTokenType.Number == tk.mType)) {
              aValue.SetFloatValue(tk.mNumber, nsCSSUnit.Pixel);
              return true;
            }
              }

              if (((aVariantMask & VARIANT_URL) != 0) &&
              nsCSSTokenType.URL == tk.mType) {
            SetValueToURL(ref aValue, tk.mIdentStr);
            return true;
              }
              if ((aVariantMask & VARIANT_GRADIENT) != 0 &&
              nsCSSTokenType.Function == tk.mType) {
            // a generated gradient
            string tmp = tk.mIdentStr;
            bool isLegacy = false;
            if (StringBeginsWith(tmp, "-moz-")) {
              tmp = tmp.Substring(5);
              isLegacy = true;
            }
            bool isRepeating = false;
            if (StringBeginsWith(tmp, "repeating-")) {
              tmp = tmp.Substring(10);
              isRepeating = true;
            }

            if (tmp.LowerCaseEqualsLiteral("linear-gradient")) {
              return ParseLinearGradient(ref aValue, isRepeating, isLegacy);
            }
            if (tmp.LowerCaseEqualsLiteral("radial-gradient")) {
              return ParseRadialGradient(ref aValue, isRepeating, isLegacy);
            }
              }
              if ((aVariantMask & VARIANT_IMAGE_RECT) != 0 &&
              nsCSSTokenType.Function == tk.mType &&
              tk.mIdentStr.LowerCaseEqualsLiteral("-moz-image-rect")) {
            return ParseImageRect(ref aValue);
              }
              if ((aVariantMask & VARIANT_ELEMENT) != 0 &&
              nsCSSTokenType.Function == tk.mType &&
              tk.mIdentStr.LowerCaseEqualsLiteral("-moz-element")) {
            return ParseElement(ref aValue);
              }
              if ((aVariantMask & VARIANT_COLOR) != 0) {
            if (mHashlessColorQuirk || // NONSTANDARD: Nav interprets 'xxyyzz' values even without '#' prefix
                (nsCSSTokenType.ID == tk.mType) ||
                (nsCSSTokenType.Hash == tk.mType) ||
                (nsCSSTokenType.Ident == tk.mType) ||
                ((nsCSSTokenType.Function == tk.mType) &&
                 (tk.mIdentStr.LowerCaseEqualsLiteral("rgb") ||
                  tk.mIdentStr.LowerCaseEqualsLiteral("hsl") ||
                  tk.mIdentStr.LowerCaseEqualsLiteral("-moz-rgba") ||
                  tk.mIdentStr.LowerCaseEqualsLiteral("-moz-hsla") ||
                  tk.mIdentStr.LowerCaseEqualsLiteral("rgba") ||
                  tk.mIdentStr.LowerCaseEqualsLiteral("hsla"))))
            {
              // Put token back so that parse color can get it
              UngetToken();
              if (ParseColor(ref aValue)) {
                return true;
              }
              return false;
            }
              }
              if (((aVariantMask & VARIANT_STRING) != 0) &&
              (nsCSSTokenType.String == tk.mType)) {
            string  buffer;
            buffer = tk.mIdentStr;
            aValue.SetStringValue(buffer, nsCSSUnit.String);
            return true;
              }
              if (((aVariantMask &
                (VARIANT_IDENTIFIER | VARIANT_IDENTIFIER_NO_INHERIT)) != 0) &&
              (nsCSSTokenType.Ident == tk.mType) &&
              ((aVariantMask & VARIANT_IDENTIFIER) != 0 ||
               !(tk.mIdentStr.LowerCaseEqualsLiteral("inherit") ||
                 tk.mIdentStr.LowerCaseEqualsLiteral("initial")))) {
            aValue.SetStringValue(tk.mIdentStr, nsCSSUnit.Ident);
            return true;
              }
              if (((aVariantMask & VARIANT_COUNTER) != 0) &&
              (nsCSSTokenType.Function == tk.mType) &&
              (tk.mIdentStr.LowerCaseEqualsLiteral("counter") ||
               tk.mIdentStr.LowerCaseEqualsLiteral("counters"))) {
            return ParseCounter(ref aValue);
              }
              if (((aVariantMask & VARIANT_ATTR) != 0) &&
              (nsCSSTokenType.Function == tk.mType) &&
              tk.mIdentStr.LowerCaseEqualsLiteral("attr")) {
            if (!ParseAttr(ref aValue)) {
              SkipUntil(')');
              return false;
            }
            return true;
              }
              if (((aVariantMask & VARIANT_TIMING_FUNCTION) != 0) &&
              (nsCSSTokenType.Function == tk.mType)) {
            if (tk.mIdentStr.LowerCaseEqualsLiteral("cubic-bezier")) {
              if (!ParseTransitionTimingFunctionValues(ref aValue)) {
                SkipUntil(')');
                return false;
              }
              return true;
            }
            if (tk.mIdentStr.LowerCaseEqualsLiteral("steps")) {
              if (!ParseTransitionStepTimingFunctionValues(ref aValue)) {
                SkipUntil(')');
                return false;
              }
              return true;
            }
              }
              if (((aVariantMask & VARIANT_CALC) != 0) &&
              (nsCSSTokenType.Function == tk.mType) &&
              (tk.mIdentStr.LowerCaseEqualsLiteral("calc") ||
               tk.mIdentStr.LowerCaseEqualsLiteral("-moz-calc"))) {
            // calc() currently allows only lengths and percents inside it.
            return ParseCalc(ref aValue, aVariantMask & VARIANT_LP);
              }

              UngetToken();
              return false;
        }