Example #1
0
        internal bool ParseRadialGradient(ref nsCSSValue aValue, bool aIsRepeating,
                                           bool aIsLegacy)
        {
            nsCSSValueGradient cssGradient
            = new nsCSSValueGradient(true, aIsRepeating);

              // [ <shape> || <size> ]
              bool haveShape =
            ParseVariant(cssGradient.GetRadialShape(), cssGradient.SetRadialShape, VARIANT_KEYWORD,
                         nsCSSProps.kRadialGradientShapeKTable);

              bool haveSize = ParseVariant(cssGradient.GetRadialSize(), cssGradient.SetRadialSize, VARIANT_KEYWORD,
                                       aIsLegacy ?
                                       nsCSSProps.kRadialGradientLegacySizeKTable :
                                       nsCSSProps.kRadialGradientSizeKTable);
              if (haveSize) {
            if (!haveShape) {
              // <size> <shape>
              haveShape = ParseVariant(cssGradient.GetRadialShape(), cssGradient.SetRadialShape, VARIANT_KEYWORD,
                                       nsCSSProps.kRadialGradientShapeKTable);
            }
              } else if (!aIsLegacy) {
            // <length> | [<length> | <percentage>]{2}
            haveSize =
              ParseNonNegativeVariant(cssGradient.GetRadiusX(), cssGradient.SetRadiusX, VARIANT_LP, null);
            if (haveSize) {
              // vertical extent is optional
              bool haveYSize =
                ParseNonNegativeVariant(cssGradient.GetRadiusY(), cssGradient.SetRadiusY, VARIANT_LP, null);
              if (!haveShape) {
                var shapeValue = new nsCSSValue();
                haveShape = ParseVariant(ref shapeValue, VARIANT_KEYWORD,
                                         nsCSSProps.kRadialGradientShapeKTable);
              }
              int32_t shape =
                cssGradient.GetRadialShape().GetUnit() == nsCSSUnit.Enumerated ?
                cssGradient.GetRadialShape().GetIntValue() : -1;
              if (haveYSize
                    ? shape == nsStyle.GRADIENT_SHAPE_CIRCULAR
                    : cssGradient.GetRadiusX().GetUnit() == nsCSSUnit.Percent ||
                      shape == nsStyle.GRADIENT_SHAPE_ELLIPTICAL) {
                SkipUntil(')');
                return false;
              }
              cssGradient.mIsExplicitSize = true;
            }
              }

              if ((haveShape || haveSize) && ExpectSymbol(',', true)) {
            // [ <shape> || <size> ] ,
            return ParseGradientColorStops(cssGradient, ref aValue);
              }

              if (!GetToken(true)) {
            return false;
              }

              if (!aIsLegacy) {
            if (mToken.mType == nsCSSTokenType.Ident &&
                mToken.mIdentStr.LowerCaseEqualsLiteral("at")) {
              // [ <shape> || <size> ]? at <position> ,
              if (!ParseBoxPositionValues(ref cssGradient.mBgPos, false) ||
                  !ExpectSymbol(',', true)) {
                SkipUntil(')');
                return false;
              }

              return ParseGradientColorStops(cssGradient, ref aValue);
            }

            // <color-stops> only
            UngetToken();
            return ParseGradientColorStops(cssGradient, ref aValue);
              }
              Debug.Assert(!cssGradient.mIsExplicitSize);

              nsCSSTokenType ty = mToken.mType;
              string id = mToken.mIdentStr;
              UngetToken();

              // <legacy-gradient-line>
              bool haveGradientLine = false;
              // if we already encountered a shape or size,
              // we can not have a gradient-line in legacy syntax
              if (!haveShape && !haveSize) {
              haveGradientLine = IsLegacyGradientLine(ty, id);
              }
              if (haveGradientLine) {
            bool haveAngle =
              ParseVariant(ref cssGradient.mAngle, VARIANT_ANGLE, null);

            // if we got an angle, we might now have a comma, ending the gradient-line
            if (!haveAngle || !ExpectSymbol(',', true)) {
              if (!ParseBoxPositionValues(ref cssGradient.mBgPos, false)) {
                SkipUntil(')');
                return false;
              }

              if (!ExpectSymbol(',', true) &&
                  // if we didn't already get an angle, we might have one now,
                  // otherwise it's an error
                  (haveAngle ||
                   !ParseVariant(ref cssGradient.mAngle, VARIANT_ANGLE, null) ||
                   // now we better have a comma
                   !ExpectSymbol(',', true))) {
                SkipUntil(')');
                return false;
              }
            }

            if (cssGradient.mAngle.GetUnit() != nsCSSUnit.None) {
              cssGradient.mIsLegacySyntax = true;
            }
              }

              // radial gradients might have a shape and size here for legacy syntax
              if (!haveShape && !haveSize) {
            haveShape =
              ParseVariant(cssGradient.GetRadialShape(), cssGradient.SetRadialShape, VARIANT_KEYWORD,
                           nsCSSProps.kRadialGradientShapeKTable);
            haveSize =
              ParseVariant(cssGradient.GetRadialSize(), cssGradient.SetRadialSize, VARIANT_KEYWORD,
                           nsCSSProps.kRadialGradientLegacySizeKTable);

            // could be in either order
            if (!haveShape) {
              haveShape =
                ParseVariant(cssGradient.GetRadialShape(), cssGradient.SetRadialShape, VARIANT_KEYWORD,
                             nsCSSProps.kRadialGradientShapeKTable);
            }
              }

              if ((haveShape || haveSize) && !ExpectSymbol(',', true)) {
            SkipUntil(')');
            return false;
              }

              return ParseGradientColorStops(cssGradient, ref aValue);
        }
Example #2
0
        // <gradient>
        //    : linear-gradient( <linear-gradient-line>? <color-stops> ')'
        //    | radial-gradient( <radial-gradient-line>? <color-stops> ')'
        //
        // <linear-gradient-line> : [ to [left | right] || [top | bottom] ] ,
        //                        | <legacy-gradient-line>
        // <radial-gradient-line> : [ <shape> || <size> ] [ at <position> ]? ,
        //                        | [ at <position> ] ,
        //                        | <legacy-gradient-line>? <legacy-shape-size>?
        // <shape> : circle | ellipse
        // <size> : closest-side | closest-corner | farthest-side | farthest-corner
        //        | <length> | [<length> | <percentage>]{2}
        //
        // <legacy-gradient-line> : [ <position> || <angle>] ,
        //
        // <legacy-shape-size> : [ <shape> || <legacy-size> ] ,
        // <legacy-size> : closest-side | closest-corner | farthest-side
        //               | farthest-corner | contain | cover
        //
        // <color-stops> : <color-stop> , <color-stop> [, <color-stop>]*
        internal bool ParseLinearGradient(ref nsCSSValue aValue, bool aIsRepeating,
                                           bool aIsLegacy)
        {
            nsCSSValueGradient cssGradient
            = new nsCSSValueGradient(false, aIsRepeating);

              if (!GetToken(true)) {
            return false;
              }

              if (mToken.mType == nsCSSTokenType.Ident &&
              mToken.mIdentStr.LowerCaseEqualsLiteral("to")) {

            // "to" syntax doesn't allow explicit "center"
            if (!ParseBoxPositionValues(ref cssGradient.mBgPos, false, false)) {
              SkipUntil(')');
              return false;
            }

            // [ to [left | right] || [top | bottom] ] ,
            nsCSSValue xValue = cssGradient.mBgPos.mXValue;
            nsCSSValue yValue = cssGradient.mBgPos.mYValue;
            if (xValue.GetUnit() != nsCSSUnit.Enumerated ||
                0 == (xValue.GetIntValue() & (nsStyle.BG_POSITION_LEFT |
                                          nsStyle.BG_POSITION_CENTER |
                                          nsStyle.BG_POSITION_RIGHT)) ||
                yValue.GetUnit() != nsCSSUnit.Enumerated ||
                0 == (yValue.GetIntValue() & (nsStyle.BG_POSITION_TOP |
                                          nsStyle.BG_POSITION_CENTER |
                                          nsStyle.BG_POSITION_BOTTOM))) {
              SkipUntil(')');
              return false;
            }

            if (!ExpectSymbol(',', true)) {
              SkipUntil(')');
              return false;
            }

            return ParseGradientColorStops(cssGradient, ref aValue);
              }

              if (!aIsLegacy) {
            UngetToken();

            // <angle> ,
            if (ParseVariant(ref cssGradient.mAngle, VARIANT_ANGLE, null) &&
                !ExpectSymbol(',', true)) {
              SkipUntil(')');
              return false;
            }

            return ParseGradientColorStops(cssGradient, ref aValue);
              }

              nsCSSTokenType ty = mToken.mType;
              string id = mToken.mIdentStr;
              UngetToken();

              // <legacy-gradient-line>
              bool haveGradientLine = IsLegacyGradientLine(ty, id);
              if (haveGradientLine) {
            cssGradient.mIsLegacySyntax = true;
            bool haveAngle =
              ParseVariant(ref cssGradient.mAngle, VARIANT_ANGLE, null);

            // if we got an angle, we might now have a comma, ending the gradient-line
            if (!haveAngle || !ExpectSymbol(',', true)) {
              if (!ParseBoxPositionValues(ref cssGradient.mBgPos, false)) {
                SkipUntil(')');
                return false;
              }

              if (!ExpectSymbol(',', true) &&
                  // if we didn't already get an angle, we might have one now,
                  // otherwise it's an error
                  (haveAngle ||
                   !ParseVariant(ref cssGradient.mAngle, VARIANT_ANGLE, null) ||
                   // now we better have a comma
                   !ExpectSymbol(',', true))) {
                SkipUntil(')');
                return false;
              }
            }
              }

              return ParseGradientColorStops(cssGradient, ref aValue);
        }
Example #3
0
        // <color-stop> : <color> [ <percentage> | <length> ]?
        internal bool ParseColorStop(nsCSSValueGradient aGradient)
        {
            nsCSSValueGradientStop stop = aGradient.mStops.AppendElement();
              if (!ParseVariant(ref stop.mColor, VARIANT_COLOR, null)) {
            return false;
              }

              // Stop positions do not have to fall between the starting-point and
              // ending-point, so we don't use ParseNonNegativeVariant.
              if (!ParseVariant(ref stop.mLocation, VARIANT_LP | VARIANT_CALC, null)) {
            stop.mLocation.SetNoneValue();
              }
              return true;
        }
Example #4
0
        internal bool ParseGradientColorStops(nsCSSValueGradient aGradient,
                                               ref nsCSSValue aValue)
        {
            // At least two color stops are required
              if (!ParseColorStop(aGradient) ||
              !ExpectSymbol(',', true) ||
              !ParseColorStop(aGradient)) {
            SkipUntil(')');
            return false;
              }

              // Additional color stops
              while (ExpectSymbol(',', true)) {
            if (!ParseColorStop(aGradient)) {
              SkipUntil(')');
              return false;
            }
              }

              if (!ExpectSymbol(')', true)) {
            SkipUntil(')');
            return false;
              }

              aValue.SetGradientValue(aGradient);
              return true;
        }
Example #5
0
 internal void SetGradientValue(CssValueGradient aValue)
 {
     mUnit  = CssUnit.Gradient;
     mValue = aValue;
 }