Пример #1
0
        // Parse one item of the background shorthand property.
        internal bool ParseBackgroundItem(BackgroundParseState aState)
        {
            // Fill in the values that the shorthand will set if we don't find
              // other values.
              aState.mImage.mValue.SetNoneValue();
              aState.mRepeat.mXValue.SetIntValue(nsStyle.BG_REPEAT_REPEAT,
                                              nsCSSUnit.Enumerated);
              aState.mRepeat.mYValue.Reset();
              aState.mAttachment.mValue.SetIntValue(nsStyle.BG_ATTACHMENT_SCROLL,
                                                 nsCSSUnit.Enumerated);
              aState.mClip.mValue.SetIntValue(nsStyle.BG_CLIP_BORDER,
                                           nsCSSUnit.Enumerated);
              aState.mOrigin.mValue.SetIntValue(nsStyle.BG_ORIGIN_PADDING,
                                             nsCSSUnit.Enumerated);
              nsCSSValue[] positionArr = new nsCSSValue[4];
              aState.mPosition.mValue.SetArrayValue(positionArr, nsCSSUnit.Array);
              positionArr[1].SetPercentValue(0.0f);
              positionArr[3].SetPercentValue(0.0f);
              aState.mSize.mXValue.SetAutoValue();
              aState.mSize.mYValue.SetAutoValue();

              bool haveColor = false,
               haveImage = false,
               haveRepeat = false,
               haveAttach = false,
               havePositionAndSize = false,
               haveOrigin = false,
               haveSomething = false;

              while (GetToken(true)) {
            nsCSSTokenType tt = mToken.mType;
            UngetToken(); // ...but we'll still cheat and use mToken
            if (tt == nsCSSTokenType.Symbol) {
              // ExpectEndProperty only looks for symbols, and nothing else will
              // show up as one.
              break;
            }

            if (tt == nsCSSTokenType.Ident) {
              nsCSSKeyword keyword = nsCSSKeywords.LookupKeyword(mToken.mIdentStr);
              int32_t dummy = 0;
              if (keyword == nsCSSKeyword.inherit ||
                  keyword == nsCSSKeyword._moz_initial ||
                  keyword == nsCSSKeyword.initial) {
                return false;
              } else if (keyword == nsCSSKeyword.none) {
                if (haveImage)
                  return false;
                haveImage = true;
                if (!ParseSingleValueProperty(ref aState.mImage.mValue,
                                              nsCSSProperty.BackgroundImage)) {
                  Debug.Fail("should be able to parse");
                  return false;
                }
              } else if (nsCSSProps.FindKeyword(keyword,
                           nsCSSProps.kBackgroundAttachmentKTable, ref dummy)) {
                if (haveAttach)
                  return false;
                haveAttach = true;
                if (!ParseSingleValueProperty(ref aState.mAttachment.mValue,
                                              nsCSSProperty.BackgroundAttachment)) {
                  Debug.Fail("should be able to parse");
                  return false;
                }
              } else if (nsCSSProps.FindKeyword(keyword,
                           nsCSSProps.kBackgroundRepeatKTable, ref dummy)) {
                if (haveRepeat)
                  return false;
                haveRepeat = true;
                var scratch = new nsCSSValuePair();
                if (!ParseBackgroundRepeatValues(ref scratch)) {
                  Debug.Fail("should be able to parse");
                  return false;
                }
                aState.mRepeat.mXValue = scratch.mXValue;
                aState.mRepeat.mYValue = scratch.mYValue;
              } else if (nsCSSProps.FindKeyword(keyword,
                           nsCSSProps.kBackgroundPositionKTable, ref dummy)) {
                if (havePositionAndSize)
                  return false;
                havePositionAndSize = true;
                if (!ParseBackgroundPositionValues(ref aState.mPosition.mValue, false)) {
                  return false;
                }
                if (ExpectSymbol('/', true)) {
                  var scratch = new nsCSSValuePair();
                  if (!ParseBackgroundSizeValues(ref scratch)) {
                    return false;
                  }
                  aState.mSize.mXValue = scratch.mXValue;
                  aState.mSize.mYValue = scratch.mYValue;
                }
              } else if (nsCSSProps.FindKeyword(keyword,
                           nsCSSProps.kBackgroundOriginKTable, ref dummy)) {
                if (haveOrigin)
                  return false;
                haveOrigin = true;
                if (!ParseSingleValueProperty(ref aState.mOrigin.mValue,
                                              nsCSSProperty.BackgroundOrigin)) {
                  Debug.Fail("should be able to parse");
                  return false;
                }

                // The spec allows a second box value (for background-clip),
                // immediately following the first one (for background-origin).

                // 'background-clip' and 'background-origin' use the same keyword table
                Debug.Assert(nsCSSProps.kKeywordTableTable[
                             (int)nsCSSProperty.BackgroundOrigin] ==
                           nsCSSProps.kBackgroundOriginKTable);
                Debug.Assert(nsCSSProps.kKeywordTableTable[
                             (int)nsCSSProperty.BackgroundClip] ==
                           nsCSSProps.kBackgroundOriginKTable);

                if (!ParseSingleValueProperty(ref aState.mClip.mValue,
                                              nsCSSProperty.BackgroundClip)) {
                  // When exactly one <box> value is set, it is used for both
                  // 'background-origin' and 'background-clip'.
                  // See assertions above showing these values are compatible.
                  aState.mClip.mValue = aState.mOrigin.mValue;
                }
              } else {
                if (haveColor)
                  return false;
                haveColor = true;
                if (!ParseSingleValueProperty(ref aState.mColor,
                                              nsCSSProperty.BackgroundColor)) {
                  return false;
                }
              }
            } else if (tt == nsCSSTokenType.URL ||
                       (tt == nsCSSTokenType.Function &&
                        (mToken.mIdentStr.LowerCaseEqualsLiteral("linear-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("radial-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("repeating-linear-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("repeating-radial-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-linear-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-radial-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-repeating-linear-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-repeating-radial-gradient") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-image-rect") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-element")))) {
              if (haveImage)
                return false;
              haveImage = true;
              if (!ParseSingleValueProperty(ref aState.mImage.mValue,
                                            nsCSSProperty.BackgroundImage)) {
                return false;
              }
            } else if (tt == nsCSSTokenType.Dimension ||
                       tt == nsCSSTokenType.Number ||
                       tt == nsCSSTokenType.Percentage ||
                       (tt == nsCSSTokenType.Function &&
                        (mToken.mIdentStr.LowerCaseEqualsLiteral("calc") ||
                         mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-calc")))) {
              if (havePositionAndSize)
                return false;
              havePositionAndSize = true;
              if (!ParseBackgroundPositionValues(ref aState.mPosition.mValue, false)) {
                return false;
              }
              if (ExpectSymbol('/', true)) {
                var scratch = new nsCSSValuePair();
                if (!ParseBackgroundSizeValues(ref scratch)) {
                  return false;
                }
                aState.mSize.mXValue = scratch.mXValue;
                aState.mSize.mYValue = scratch.mYValue;
              }
            } else {
              if (haveColor)
                return false;
              haveColor = true;
              // Note: This parses 'inherit' and 'initial', but
              // we've already checked for them, so it's ok.
              if (!ParseSingleValueProperty(ref aState.mColor,
                                            nsCSSProperty.BackgroundColor)) {
                return false;
              }
            }
            haveSomething = true;
              }

              return haveSomething;
        }
Пример #2
0
        internal bool ParseBackground()
        {
            using (/*var compound = */new nsAutoParseCompoundProperty(this)) {

            // background-color can only be set once, so it's not a list.
            var color = new nsCSSValue();

            // Check first for inherit/initial.
            if (ParseVariant(ref color, VARIANT_INHERIT, null)) {
              // must be alone
              if (!ExpectEndProperty()) {
                return false;
              }
              AppendValues(nsCSSProps.SubpropertyEntryFor(nsCSSProperty.Background), color);
              return true;
            }

            nsCSSValue image = new nsCSSValue(), repeat = new nsCSSValue(), attachment = new nsCSSValue(), clip = new nsCSSValue(), origin = new nsCSSValue(), position = new nsCSSValue(), size = new nsCSSValue();
            var state = new BackgroundParseState(color, image.SetListValue(),
                                       repeat.SetPairListValue(),
                                       attachment.SetListValue(), clip.SetListValue(),
                                       origin.SetListValue(), position.SetListValue(),
                                       size.SetPairListValue());

            for (;;) {
              if (!ParseBackgroundItem(state)) {
                return false;
              }
              if (CheckEndProperty()) {
                break;
              }
              // If we saw a color, this must be the last item.
              if (color.GetUnit() != nsCSSUnit.Null) {
                { if (!mSuppressErrors) mReporter.ReportUnexpected("PEExpectEndValue", mToken); };
                return false;
              }
              // Otherwise, a comma is mandatory.
              if (!ExpectSymbol(',', true)) {
                return false;
              }
              // Chain another entry on all the lists.
              state.mImage.mNext = new nsCSSValueList();
              state.mImage = state.mImage.mNext;
              state.mRepeat.mNext = new nsCSSValuePairList();
              state.mRepeat = state.mRepeat.mNext;
              state.mAttachment.mNext = new nsCSSValueList();
              state.mAttachment = state.mAttachment.mNext;
              state.mClip.mNext = new nsCSSValueList();
              state.mClip = state.mClip.mNext;
              state.mOrigin.mNext = new nsCSSValueList();
              state.mOrigin = state.mOrigin.mNext;
              state.mPosition.mNext = new nsCSSValueList();
              state.mPosition = state.mPosition.mNext;
              state.mSize.mNext = new nsCSSValuePairList();
              state.mSize = state.mSize.mNext;
            }

            // If we get to this point without seeing a color, provide a default.
            if (color.GetUnit() == nsCSSUnit.Null) {
              color.SetColorValue(nscolor.RGBA(0,0,0,0));
            }

            AppendValue(nsCSSProperty.BackgroundImage,      image);
            AppendValue(nsCSSProperty.BackgroundRepeat,     repeat);
            AppendValue(nsCSSProperty.BackgroundAttachment, attachment);
            AppendValue(nsCSSProperty.BackgroundClip,       clip);
            AppendValue(nsCSSProperty.BackgroundOrigin,     origin);
            AppendValue(nsCSSProperty.BackgroundPosition,   position);
            AppendValue(nsCSSProperty.BackgroundSize,       size);
            AppendValue(nsCSSProperty.BackgroundColor,      color);
            return true;
              }
        }