Пример #1
0
        internal bool ParsePaintOrder()
        {
            /*TODO: static*/ int32_t[] kPaintOrderKTable = {
            (int32_t)nsCSSKeyword.normal,  nsStyle.PAINT_ORDER_NORMAL,
            (int32_t)nsCSSKeyword.fill,    nsStyle.PAINT_ORDER_FILL,
            (int32_t)nsCSSKeyword.stroke,  nsStyle.PAINT_ORDER_STROKE,
            (int32_t)nsCSSKeyword.markers, nsStyle.PAINT_ORDER_MARKERS,
            (int32_t)nsCSSKeyword.UNKNOWN,-1
              };

              var value = new nsCSSValue();
              if (!ParseVariant(ref value, VARIANT_HK, kPaintOrderKTable)) {
            return false;
              }

              uint32_t seen = 0;
              uint32_t order = 0;
              uint32_t position = 0;

              // Ensure that even cast to a signed int32_t when stored in CSSValue,
              // we have enough space for the entire paint-order value.

              if (value.GetUnit() == nsCSSUnit.Enumerated) {
            uint32_t component = ((uint32_t)(value.GetIntValue()));
            if (component != nsStyle.PAINT_ORDER_NORMAL) {
              bool parsedOK = true;
              for (;;) {
                if (((seen & (1 << component)) != 0)) {
                  // Already seen this component.
                  UngetToken();
                  parsedOK = false;
                  break;
                }
                seen |= (1 << component);
                order |= (component << position);
                position += nsStyle.PAINT_ORDER_BITWIDTH;
                if (!ParseEnum(ref value, kPaintOrderKTable)) {
                  break;
                }
                component = value.GetIntValue();
                if (component == nsStyle.PAINT_ORDER_NORMAL) {
                  // Can't have "normal" in the middle of the list of paint components.
                  UngetToken();
                  parsedOK = false;
                  break;
                }
              }

              // Fill in the remaining paint-order components in the order of their
              // constant values.
              if (parsedOK) {
                for (component = 1;
                     component <= nsStyle.PAINT_ORDER_LAST_VALUE;
                     component++) {
                  if (!(((seen & (1 << component)) != 0))) {
                    order |= (component << position);
                    position += nsStyle.PAINT_ORDER_BITWIDTH;
                  }
                }
              }
            }
            value.SetIntValue(((int32_t)(order)), nsCSSUnit.Enumerated);
              }

              if (!ExpectEndProperty()) {
            return false;
              }

              AppendValue(nsCSSProperty.PaintOrder, value);
              return true;
        }
Пример #2
0
        internal bool ParseOverflow()
        {
            var overflow = new nsCSSValue();
              if (!ParseVariant(ref overflow, VARIANT_HK,
                            nsCSSProps.kOverflowKTable) ||
              !ExpectEndProperty())
            return false;

              var overflowX = new nsCSSValue(overflow);
              var overflowY = new nsCSSValue(overflow);
              if (nsCSSUnit.Enumerated == overflow.GetUnit())
            switch(overflow.GetIntValue()) {
              case nsStyle.OVERFLOW_SCROLLBARS_HORIZONTAL:
                overflowX.SetIntValue(nsStyle.OVERFLOW_SCROLL, nsCSSUnit.Enumerated);
                overflowY.SetIntValue(nsStyle.OVERFLOW_HIDDEN, nsCSSUnit.Enumerated);
                break;
              case nsStyle.OVERFLOW_SCROLLBARS_VERTICAL:
                overflowX.SetIntValue(nsStyle.OVERFLOW_HIDDEN, nsCSSUnit.Enumerated);
                overflowY.SetIntValue(nsStyle.OVERFLOW_SCROLL, nsCSSUnit.Enumerated);
                break;
            }
              AppendValue(nsCSSProperty.OverflowX, overflowX);
              AppendValue(nsCSSProperty.OverflowY, overflowY);
              return true;
        }
Пример #3
0
        internal bool ParsePaint(nsCSSProperty aPropID)
        {
            nsCSSValue x = new nsCSSValue(), y = new nsCSSValue();
              if (!ParseVariant(ref x, VARIANT_HCK | VARIANT_NONE | VARIANT_URL,
                            nsCSSProps.kObjectPatternKTable)) {
            return false;
              }

              bool canHaveFallback = x.GetUnit() == nsCSSUnit.Url ||
                                 x.GetUnit() == nsCSSUnit.Enumerated;
              if (canHaveFallback) {
            if (!ParseVariant(ref y, VARIANT_COLOR | VARIANT_NONE, null))
              y.SetNoneValue();
              }
              if (!ExpectEndProperty())
            return false;

              if (!canHaveFallback) {
            AppendValue(aPropID, x);
              } else {
            var val = new nsCSSValue();
            val.SetPairValue(x, y);
            AppendValue(aPropID, val);
              }
              return true;
        }
Пример #4
0
        // flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
        internal bool ParseFlex()
        {
            // First check for inherit / initial
              var tmpVal = new nsCSSValue();
              if (ParseVariant(ref tmpVal, VARIANT_INHERIT, null)) {
            AppendValue(nsCSSProperty.FlexGrow, tmpVal);
            AppendValue(nsCSSProperty.FlexShrink, tmpVal);
            AppendValue(nsCSSProperty.FlexBasis, tmpVal);
            return true;
              }

              // Next, check for 'none' == '0 0 auto'
              if (ParseVariant(ref tmpVal, VARIANT_NONE, null)) {
            AppendValue(nsCSSProperty.FlexGrow, new nsCSSValue(0.0f, nsCSSUnit.Number));
            AppendValue(nsCSSProperty.FlexShrink, new nsCSSValue(0.0f, nsCSSUnit.Number));
            AppendValue(nsCSSProperty.FlexBasis, new nsCSSValue(nsCSSUnit.Auto));
            return true;
              }

              // OK, try parsing our value as individual per-subproperty components:
              //   [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

              // Each subproperty has a default value that it takes when it's omitted in a
              // "flex" shorthand value. These default values are *only* for the shorthand
              // syntax -- they're distinct from the subproperties' own initial values.  We
              // start with each subproperty at its default, as if we had "flex: 1 1 0%".
              var flexGrow = new nsCSSValue(1.0f, nsCSSUnit.Number);
              var flexShrink = new nsCSSValue(1.0f, nsCSSUnit.Number);
              var flexBasis = new nsCSSValue(0.0f, nsCSSUnit.Percent);

              // OVERVIEW OF PARSING STRATEGY:
              // =============================
              // a) Parse the first component as either flex-basis or flex-grow.
              // b) If it wasn't flex-grow, parse the _next_ component as flex-grow.
              // c) Now we've just parsed flex-grow -- so try parsing the next thing as
              //    flex-shrink.
              // d) Finally: If we didn't get flex-basis at the beginning, try to parse
              //    it now, at the end.
              //
              // More details in each section below.

              uint32_t flexBasisVariantMask =
            (nsCSSProps.ParserVariant(nsCSSProperty.FlexBasis) & ~(VARIANT_INHERIT));

              // (a) Parse first component. It can be either be a 'flex-basis' value or a
              // 'flex-grow' value, so we use the flex-basis-specific variant mask, along
              //  with VARIANT_NUMBER to accept 'flex-grow' values.
              //
              // NOTE: if we encounter unitless 0 here, we *must* interpret it as a
              // 'flex-grow' value (a number), *not* as a 'flex-basis' value (a length).
              // Conveniently, that's the behavior this combined variant-mask gives us --
              // it'll treat unitless 0 as a number. The flexbox spec requires this:
              // "a unitless zero that is not already preceded by two flex factors must be
              //  interpreted as a flex factor.
              if (!ParseNonNegativeVariant(ref tmpVal, flexBasisVariantMask | VARIANT_NUMBER,
                                       nsCSSProps.kWidthKTable)) {
            // First component was not a valid flex-basis or flex-grow value. Fail.
            return false;
              }

              // Record what we just parsed as either flex-basis or flex-grow:
              bool wasFirstComponentFlexBasis = (tmpVal.GetUnit() != nsCSSUnit.Number);
              if (wasFirstComponentFlexBasis) flexBasis = tmpVal; else flexGrow = tmpVal;

              // (b) If we didn't get flex-grow yet, parse _next_ component as flex-grow.
              bool doneParsing = false;
              if (wasFirstComponentFlexBasis) {
            if (ParseNonNegativeVariant(ref tmpVal, VARIANT_NUMBER, null)) {
              flexGrow = tmpVal;
            } else {
              // Failed to parse anything after our flex-basis -- that's fine. We can
              // skip the remaining parsing.
              doneParsing = true;
            }
              }

              if (!doneParsing) {
            // (c) OK -- the last thing we parsed was flex-grow, so look for a
            //     flex-shrink in the next position.
            if (ParseNonNegativeVariant(ref tmpVal, VARIANT_NUMBER, null)) {
              flexShrink = tmpVal;
            }

            // d) Finally: If we didn't get flex-basis at the beginning, try to parse
            //    it now, at the end.
            //
            // NOTE: If we encounter unitless 0 in this final position, we'll parse it
            // as a 'flex-basis' value.  That's OK, because we know it must have
            // been "preceded by 2 flex factors" (justification below), which gets us
            // out of the spec's requirement of otherwise having to treat unitless 0
            // as a flex factor.
            //
            // JUSTIFICATION: How do we know that a unitless 0 here must have been
            // preceded by 2 flex factors? Well, suppose we had a unitless 0 that
            // was preceded by only 1 flex factor.  Then, we would have already
            // accepted this unitless 0 as the 'flex-shrink' value, up above (since
            // it's a valid flex-shrink value), and we'd have moved on to the next
            // token (if any). And of course, if we instead had a unitless 0 preceded
            // by *no* flex factors (if it were the first token), we would've already
            // parsed it in our very first call to ParseNonNegativeVariant().  So, any
            // unitless 0 encountered here *must* have been preceded by 2 flex factors.
            if (!wasFirstComponentFlexBasis &&
                ParseNonNegativeVariant(ref tmpVal, flexBasisVariantMask,
                                        nsCSSProps.kWidthKTable)) {
              flexBasis = tmpVal;
            }
              }

              AppendValue(nsCSSProperty.FlexGrow,   flexGrow);
              AppendValue(nsCSSProperty.FlexShrink, flexShrink);
              AppendValue(nsCSSProperty.FlexBasis,  flexBasis);

              return true;
        }
 public float ComputeNumber(CssValue aValue)
 {
     Debug.Assert(aValue.GetUnit() == CssUnit.Number, "unexpected unit");
     return aValue.GetFloatValue();
 }
Пример #6
0
        internal bool ParseSize()
        {
            nsCSSValue width = new nsCSSValue(), height = new nsCSSValue();
              if (!ParseVariant(ref width, VARIANT_AHKL, nsCSSProps.kPageSizeKTable)) {
            return false;
              }
              if (width.IsLengthUnit()) {
            ParseVariant(ref height, VARIANT_LENGTH, null);
              }
              if (!ExpectEndProperty()) {
            return false;
              }

              if (width == height || height.GetUnit() == nsCSSUnit.Null) {
            AppendValue(nsCSSProperty.Size, width);
              } else {
            var pair = new nsCSSValue();
            pair.SetPairValue(width, height);
            AppendValue(nsCSSProperty.Size, pair);
              }
              return true;
        }
Пример #7
0
 internal bool ParseTextDecorationLine(ref nsCSSValue aValue)
 {
     if (ParseVariant(ref aValue, VARIANT_HK, nsCSSProps.kTextDecorationLineKTable)) {
     if (nsCSSUnit.Enumerated == aValue.GetUnit()) {
       int32_t intValue = aValue.GetIntValue();
       if (intValue != nsStyle.TEXT_DECORATION_LINE_NONE) {
         // look for more keywords
         var keyword = new nsCSSValue();
         int32_t index = 0;
         for (index = 0; index < 2; index++) {
           if (ParseEnum(ref keyword, nsCSSProps.kTextDecorationLineKTable)) {
             int32_t newValue = keyword.GetIntValue();
             if (newValue == nsStyle.TEXT_DECORATION_LINE_NONE ||
                 ((newValue & intValue) != 0)) {
               // 'none' keyword in conjuction with others is not allowed, and
               // duplicate keyword is not allowed.
               return false;
             }
             intValue |= newValue;
           }
           else {
             break;
           }
         }
         aValue.SetIntValue(intValue, nsCSSUnit.Enumerated);
       }
     }
     return true;
       }
       return false;
 }
Пример #8
0
 //  * If aVariantMask is VARIANT_NUMBER, this function parses the
 //    <number-term> production.
 //  * If aVariantMask does not contain VARIANT_NUMBER, this function
 //    parses the <value-term> production.
 //  * Otherwise (VARIANT_NUMBER and other bits) this function parses
 //    whichever one of the productions matches ***and modifies
 //    aVariantMask*** to reflect which one it has parsed by either
 //    removing VARIANT_NUMBER or removing all other bits.
 internal bool ParseCalcTerm(ref nsCSSValue aValue, ref int32_t aVariantMask)
 {
     Debug.Assert(aVariantMask != 0, "unexpected variant mask");
       if (!GetToken(true))
     return false;
       // Either an additive expression in parentheses...
       if (mToken.IsSymbol('(')) {
     if (!ParseCalcAdditiveExpression(ref aValue, ref aVariantMask) ||
         !ExpectSymbol(')', true)) {
       SkipUntil(')');
       return false;
     }
     return true;
       }
       // ... or just a value
       UngetToken();
       // Always pass VARIANT_NUMBER to ParseVariant so that unitless zero
       // always gets picked up
       if (!ParseVariant(ref aValue, aVariantMask | VARIANT_NUMBER, null)) {
     return false;
       }
       // ...and do the VARIANT_NUMBER check ourselves.
       if (!((aVariantMask & VARIANT_NUMBER) != 0) && aValue.GetUnit() == nsCSSUnit.Number) {
     return false;
       }
       // If we did the value parsing, we need to adjust aVariantMask to
       // reflect which option we took (see above).
       if ((aVariantMask & VARIANT_NUMBER) != 0) {
     if (aValue.GetUnit() == nsCSSUnit.Number) {
       aVariantMask = VARIANT_NUMBER;
     } else {
       aVariantMask &= ~((int32_t)(VARIANT_NUMBER));
     }
       }
       return true;
 }
Пример #9
0
        internal bool ParseFont()
        {
            /*TODO: static*/ nsCSSProperty[] fontIDs = {
            nsCSSProperty.FontStyle,
            nsCSSProperty.FontVariant,
            nsCSSProperty.FontWeight
              };

              var family = new nsCSSValue();
              if (ParseVariant(ref family, VARIANT_HK, nsCSSProps.kFontKTable)) {
            if (ExpectEndProperty()) {
              if (nsCSSUnit.Inherit == family.GetUnit() ||
                  nsCSSUnit.Initial == family.GetUnit()) {
                AppendValue(nsCSSProperty.XSystemFont, new nsCSSValue(nsCSSUnit.None));
                AppendValue(nsCSSProperty.FontFamily, family);
                AppendValue(nsCSSProperty.FontStyle, family);
                AppendValue(nsCSSProperty.FontVariant, family);
                AppendValue(nsCSSProperty.FontWeight, family);
                AppendValue(nsCSSProperty.FontSize, family);
                AppendValue(nsCSSProperty.LineHeight, family);
                AppendValue(nsCSSProperty.FontStretch, family);
                AppendValue(nsCSSProperty.FontSizeAdjust, family);
                AppendValue(nsCSSProperty.FontFeatureSettings, family);
                AppendValue(nsCSSProperty.FontLanguageOverride, family);
              }
              else {
                AppendValue(nsCSSProperty.XSystemFont, family);
                var systemFont = new nsCSSValue(nsCSSUnit.SystemFont);
                AppendValue(nsCSSProperty.FontFamily, systemFont);
                AppendValue(nsCSSProperty.FontStyle, systemFont);
                AppendValue(nsCSSProperty.FontVariant, systemFont);
                AppendValue(nsCSSProperty.FontWeight, systemFont);
                AppendValue(nsCSSProperty.FontSize, systemFont);
                AppendValue(nsCSSProperty.LineHeight, systemFont);
                AppendValue(nsCSSProperty.FontStretch, systemFont);
                AppendValue(nsCSSProperty.FontSizeAdjust, systemFont);
                AppendValue(nsCSSProperty.FontFeatureSettings, systemFont);
                AppendValue(nsCSSProperty.FontLanguageOverride, systemFont);
              }
              return true;
            }
            return false;
              }

              // Get optional font-style, font-variant and font-weight (in any order)
              uint32_t numProps = 3;
              var values = new nsCSSValue[numProps];
              int32_t found = ParseChoice(ref values, fontIDs, numProps);
              if ((found < 0) || (nsCSSUnit.Inherit == values[0].GetUnit()) ||
              (nsCSSUnit.Initial == values[0].GetUnit())) { // illegal data
            return false;
              }
              if ((found & 1) == 0) {
            // Provide default font-style
            values[0].SetIntValue(nsFont.STYLE_NORMAL, nsCSSUnit.Enumerated);
              }
              if ((found & 2) == 0) {
            // Provide default font-variant
            values[1].SetIntValue(nsFont.VARIANT_NORMAL, nsCSSUnit.Enumerated);
              }
              if ((found & 4) == 0) {
            // Provide default font-weight
            values[2].SetIntValue(nsFont.WEIGHT_NORMAL, nsCSSUnit.Enumerated);
              }

              // Get mandatory font-size
              var size = new nsCSSValue();
              if (! ParseVariant(ref size, VARIANT_KEYWORD | VARIANT_LP, nsCSSProps.kFontSizeKTable)) {
            return false;
              }

              // Get optional "/" line-height
              var lineHeight = new nsCSSValue();
              if (ExpectSymbol('/', true)) {
            if (! ParseNonNegativeVariant(ref lineHeight,
                                          VARIANT_NUMBER | VARIANT_LP | VARIANT_NORMAL,
                                          null)) {
              return false;
            }
              }
              else {
            lineHeight.SetNormalValue();
              }

              // Get final mandatory font-family
              using (/*var compound = */new nsAutoParseCompoundProperty(this)) {
            if (ParseFamily(ref family)) {
              if ((nsCSSUnit.Inherit != family.GetUnit()) && (nsCSSUnit.Initial != family.GetUnit()) &&
                  ExpectEndProperty()) {
                AppendValue(nsCSSProperty.XSystemFont, new nsCSSValue(nsCSSUnit.None));
                AppendValue(nsCSSProperty.FontFamily, family);
                AppendValue(nsCSSProperty.FontStyle, values[0]);
                AppendValue(nsCSSProperty.FontVariant, values[1]);
                AppendValue(nsCSSProperty.FontWeight, values[2]);
                AppendValue(nsCSSProperty.FontSize, size);
                AppendValue(nsCSSProperty.LineHeight, lineHeight);
                AppendValue(nsCSSProperty.FontStretch,
                            new nsCSSValue(nsFont.STRETCH_NORMAL, nsCSSUnit.Enumerated));
                AppendValue(nsCSSProperty.FontSizeAdjust, new nsCSSValue(nsCSSUnit.None));
                AppendValue(nsCSSProperty.FontFeatureSettings, new nsCSSValue(nsCSSUnit.Normal));
                AppendValue(nsCSSProperty.FontLanguageOverride, new nsCSSValue(nsCSSUnit.Normal));
                return true;
              }
            }
            return false;
              }
        }
Пример #10
0
        internal bool ParseBorderSpacing()
        {
            nsCSSValue xValue = new nsCSSValue(), yValue = new nsCSSValue();
              if (!ParseNonNegativeVariant(ref xValue, VARIANT_HL | VARIANT_CALC, null)) {
            return false;
              }

              // If we have one length, get the optional second length.
              // set the second value equal to the first.
              if (xValue.IsLengthUnit() || xValue.IsCalcUnit()) {
            ParseNonNegativeVariant(ref yValue, VARIANT_LENGTH | VARIANT_CALC, null);
              }

              if (!ExpectEndProperty()) {
            return false;
              }

              if (yValue == xValue || yValue.GetUnit() == nsCSSUnit.Null) {
            AppendValue(nsCSSProperty.BorderSpacing, xValue);
              } else {
            var pair = new nsCSSValue();
            pair.SetPairValue(xValue, yValue);
            AppendValue(nsCSSProperty.BorderSpacing, pair);
              }
              return true;
        }
Пример #11
0
        internal bool ParseBoxCornerRadius(nsCSSProperty aPropID)
        {
            nsCSSValue dimenX = new nsCSSValue(), dimenY = new nsCSSValue();
              // required first value
              if (! ParseNonNegativeVariant(ref dimenX, VARIANT_HLP | VARIANT_CALC, null))
            return false;

              // optional second value (forbidden if first value is inherit/initial)
              if (dimenX.GetUnit() != nsCSSUnit.Inherit &&
              dimenX.GetUnit() != nsCSSUnit.Initial) {
            ParseNonNegativeVariant(ref dimenY, VARIANT_LP | VARIANT_CALC, null);
              }

              if (dimenX == dimenY || dimenY.GetUnit() == nsCSSUnit.Null) {
            AppendValue(aPropID, dimenX);
              } else {
            var value = new nsCSSValue();
            value.SetPairValue(dimenX, dimenY);
            AppendValue(aPropID, value);
              }
              return true;
        }
Пример #12
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;
              }
        }
Пример #13
0
        internal bool ParseTextDecoration()
        {
            const int eDecorationNone         = nsStyle.TextDecorationLineNone;
              const int eDecorationUnderline    = nsStyle.TextDecorationLineUnderline;
              const int eDecorationOverline     = nsStyle.TextDecorationLineOverline;
              const int eDecorationLineThrough  = nsStyle.TextDecorationLineLineThrough;
              const int eDecorationBlink        = nsStyle.TextDecorationLineBlink;
              const int eDecorationPrefAnchors  = nsStyle.TextDecorationLinePrefAnchors;

              /*TODO: static*/ int32_t[] kTextDecorationKTable = {
            (int32_t)nsCSSKeyword.None,                   eDecorationNone,
            (int32_t)nsCSSKeyword.Underline,              eDecorationUnderline,
            (int32_t)nsCSSKeyword.Overline,               eDecorationOverline,
            (int32_t)nsCSSKeyword.LineThrough,           eDecorationLineThrough,
            (int32_t)nsCSSKeyword.Blink,                  eDecorationBlink,
            (int32_t)nsCSSKeyword.MozAnchorDecoration, eDecorationPrefAnchors,
            (int32_t)nsCSSKeyword.Unknown,-1
              };

              var value = new nsCSSValue();
              if (!ParseVariant(ref value, VARIANT_HK, kTextDecorationKTable)) {
            return false;
              }

              nsCSSValue blink = new nsCSSValue(), line = new nsCSSValue(), style = new nsCSSValue(), color = new nsCSSValue();
              switch (value.GetUnit()) {
            case nsCSSUnit.Enumerated: {
              // We shouldn't accept decoration line style and color via
              // text-decoration.
              color.SetIntValue(nsStyle.ColorMozUseTextColor,
                                nsCSSUnit.Enumerated);
              style.SetIntValue(nsStyle.TextDecorationStyleSolid,
                                nsCSSUnit.Enumerated);

              int32_t intValue = value.GetIntValue();
              if (intValue == eDecorationNone) {
                blink.SetIntValue(nsStyle.TextBlinkNone, nsCSSUnit.Enumerated);
                line.SetIntValue(nsStyle.TextDecorationLineNone,
                                 nsCSSUnit.Enumerated);
                break;
              }

              // look for more keywords
              var keyword = new nsCSSValue();
              int32_t index = 0;
              for (index = 0; index < 3; index++) {
                if (!ParseEnum(ref keyword, kTextDecorationKTable)) {
                  break;
                }
                int32_t newValue = keyword.GetIntValue();
                if (newValue == eDecorationNone || ((newValue & intValue) != 0)) {
                  // 'none' keyword in conjuction with others is not allowed, and
                  // duplicate keyword is not allowed.
                  return false;
                }
                intValue |= newValue;
              }

              blink.SetIntValue((intValue & eDecorationBlink) != 0 ?
                                  nsStyle.TextBlinkBlink : nsStyle.TextBlinkNone,
                                nsCSSUnit.Enumerated);
              line.SetIntValue((intValue & ~eDecorationBlink), nsCSSUnit.Enumerated);
              break;
            }
              goto default;
            default:
              blink = line = color = style = value;
              break;
              }

              AppendValue(nsCSSProperty.TextBlink, blink);
              AppendValue(nsCSSProperty.TextDecorationLine, line);
              AppendValue(nsCSSProperty.TextDecorationColor, color);
              AppendValue(nsCSSProperty.TextDecorationStyle, style);

              return true;
        }
Пример #14
0
        internal bool ParseOverflow()
        {
            var overflow = new nsCSSValue();
              if (!ParseVariant(ref overflow, VARIANT_HK,
                            nsCSSProps.kOverflowKTable) ||
              !ExpectEndProperty())
            return false;

              var overflowX = new nsCSSValue(overflow);
              var overflowY = new nsCSSValue(overflow);
              if (nsCSSUnit.Enumerated == overflow.GetUnit())
            switch(overflow.GetIntValue()) {
              case nsStyle.OverflowScrollbarsHorizontal:
                overflowX.SetIntValue(nsStyle.OverflowScroll, nsCSSUnit.Enumerated);
                overflowY.SetIntValue(nsStyle.OverflowHidden, nsCSSUnit.Enumerated);
                break;
              case nsStyle.OverflowScrollbarsVertical:
                overflowX.SetIntValue(nsStyle.OverflowHidden, nsCSSUnit.Enumerated);
                overflowY.SetIntValue(nsStyle.OverflowScroll, nsCSSUnit.Enumerated);
                break;
            }
              AppendValue(nsCSSProperty.OverflowX, overflowX);
              AppendValue(nsCSSProperty.OverflowY, overflowY);
              return true;
        }
Пример #15
0
 internal bool ParseQuotes()
 {
     var value = new nsCSSValue();
       if (!ParseVariant(ref value, VARIANT_HOS, null)) {
     return false;
       }
       if (value.GetUnit() != nsCSSUnit.String) {
     if (!ExpectEndProperty()) {
       return false;
     }
       } else {
     nsCSSValue open = value;
     nsCSSValuePairList quotes = value.SetPairListValue();
     for (;;) {
       quotes.mXValue = open;
       // get mandatory close
       if (!ParseVariant(ref quotes.mYValue, VARIANT_STRING, null)) {
         return false;
       }
       if (CheckEndProperty()) {
         break;
       }
       // look for another open
       if (!ParseVariant(ref open, VARIANT_STRING, null)) {
         return false;
       }
       quotes.mNext = new nsCSSValuePairList();
       quotes = quotes.mNext;
     }
       }
       AppendValue(nsCSSProperty.Quotes, value);
       return true;
 }
Пример #16
0
        // font-descriptor: descriptor ':' value ';'
        // caller has advanced mToken to point at the descriptor
        internal bool ParseFontDescriptorValue(nsCSSFontDesc aDescID,
                                                ref nsCSSValue aValue)
        {
            switch (aDescID) {
            // These four are similar to the properties of the same name,
            // possibly with more restrictions on the values they can take.

              case nsCSSFontDesc.Family: {
            if (!ParseFamily(ref aValue) ||
                aValue.GetUnit() != nsCSSUnit.Families)
              return false;

            // the style parameters to the nsFont constructor are ignored,
            // because it's only being used to call EnumerateFamilies
            string valueStr = "";
            aValue.GetStringValue(ref valueStr);
            var font = new nsFont(valueStr, 0, 0, 0, 0, 0, 0);
            var dat = new ExtractFirstFamilyData();

            font.EnumerateFamilies(ExtractFirstFamily, (object) dat);
            if (!dat.mGood)
              return false;

            aValue.SetStringValue(dat.mFamilyName, nsCSSUnit.String);
            return true;
              }

            goto case nsCSSFontDesc.Style;
              case nsCSSFontDesc.Style:
            // property is VARIANT_HMK|VARIANT_SYSFONT
            return ParseVariant(ref aValue, VARIANT_KEYWORD | VARIANT_NORMAL,
                                nsCSSProps.kFontStyleKTable);

              case nsCSSFontDesc.Weight:
            return (ParseFontWeight(ref aValue) &&
                    aValue.GetUnit() != nsCSSUnit.Inherit &&
                    aValue.GetUnit() != nsCSSUnit.Initial &&
                    (aValue.GetUnit() != nsCSSUnit.Enumerated ||
                     (aValue.GetIntValue() != nsStyle.FONT_WEIGHT_BOLDER &&
                      aValue.GetIntValue() != nsStyle.FONT_WEIGHT_LIGHTER)));

              case nsCSSFontDesc.Stretch:
            // property is VARIANT_HK|VARIANT_SYSFONT
            return ParseVariant(ref aValue, VARIANT_KEYWORD,
                                nsCSSProps.kFontStretchKTable);

            // These two are unique to @font-face and have their own special grammar.
            goto case nsCSSFontDesc.Src;
              case nsCSSFontDesc.Src:
            return ParseFontSrc(ref aValue);

              case nsCSSFontDesc.UnicodeRange:
            return ParseFontRanges(ref aValue);

              case nsCSSFontDesc.FontFeatureSettings:
            return ParseFontFeatureSettings(ref aValue);

              case nsCSSFontDesc.FontLanguageOverride:
            return ParseVariant(ref aValue, VARIANT_NORMAL | VARIANT_STRING, null);

              case nsCSSFontDesc.UNKNOWN:
              case nsCSSFontDesc.COUNT:
            Debug.Fail("bad nsCSSFontDesc code");
            break;
              }
              // explicitly do NOT have a default case to let the compiler
              // help find missing descriptors
              return false;
        }
Пример #17
0
        internal bool ParseShadowItem(ref nsCSSValue aValue, bool aIsBoxShadow)
        {
            // A shadow list item is an array, with entries in this sequence:
              const int IndexX = 0;
              const int IndexY = 1;
              const int IndexRadius = 2;
              const int IndexSpread = 3;
              const int IndexColor = 4;
              const int IndexInset = 5;

              nsCSSValue[] val = new nsCSSValue[6];

              if (aIsBoxShadow) {
            // Optional inset keyword (ignore errors)
            ParseVariant(ref val[IndexInset], VARIANT_KEYWORD,
                         nsCSSProps.kBoxShadowTypeKTable);
              }

              var xOrColor = new nsCSSValue();
              bool haveColor = false;
              if (!ParseVariant(ref xOrColor, VARIANT_COLOR | VARIANT_LENGTH | VARIANT_CALC,
                            null)) {
            return false;
              }
              if (xOrColor.IsLengthUnit() || xOrColor.IsCalcUnit()) {
            val[IndexX] = xOrColor;
              } else {
            // Must be a color (as string or color value)
            Debug.Assert(xOrColor.GetUnit() == nsCSSUnit.Ident ||
                         xOrColor.GetUnit() == nsCSSUnit.Color ||
                         xOrColor.GetUnit() == nsCSSUnit.EnumColor,
                         "Must be a color value");
            val[IndexColor] = xOrColor;
            haveColor = true;

            // X coordinate mandatory after color
            if (!ParseVariant(ref val[IndexX], VARIANT_LENGTH | VARIANT_CALC,
                              null)) {
              return false;
            }
              }

              // Y coordinate; mandatory
              if (!ParseVariant(ref val[IndexY], VARIANT_LENGTH | VARIANT_CALC,
                            null)) {
            return false;
              }

              // Optional radius. Ignore errors except if they pass a negative
              // value which we must reject. If we use ParseNonNegativeVariant
              // we can't tell the difference between an unspecified radius
              // and a negative radius.
              if (ParseVariant(ref val[IndexRadius], VARIANT_LENGTH | VARIANT_CALC,
                           null) &&
              val[IndexRadius].IsLengthUnit() &&
              val[IndexRadius].GetFloatValue() < 0) {
            return false;
              }

              if (aIsBoxShadow) {
            // Optional spread
            ParseVariant(ref val[IndexSpread], VARIANT_LENGTH | VARIANT_CALC, null);
              }

              if (!haveColor) {
            // Optional color
            ParseVariant(ref val[IndexColor], VARIANT_COLOR, null);
              }

              if (aIsBoxShadow && val[IndexInset].GetUnit() == nsCSSUnit.Null) {
            // Optional inset keyword
            ParseVariant(ref val[IndexInset], VARIANT_KEYWORD,
                         nsCSSProps.kBoxShadowTypeKTable);
              }

              aValue.SetArrayValue(val, nsCSSUnit.Array);
              return true;
        }
Пример #18
0
 internal bool ParseFontWeight(ref nsCSSValue aValue)
 {
     if (ParseVariant(ref aValue, VARIANT_HKI | VARIANT_SYSFONT,
                    nsCSSProps.kFontWeightKTable)) {
     if (nsCSSUnit.Integer == aValue.GetUnit()) { // ensure unit value
       int32_t intValue = aValue.GetIntValue();
       if ((100 <= intValue) &&
           (intValue <= 900) &&
           (0 == (intValue % 100))) {
         return true;
       } else {
         UngetToken();
         return false;
       }
     }
     return true;
       }
       return false;
 }
Пример #19
0
        internal bool ParseTextDecoration()
        {
            const int eDecorationNone         = nsStyle.TEXT_DECORATION_LINE_NONE;
              const int eDecorationUnderline    = nsStyle.TEXT_DECORATION_LINE_UNDERLINE;
              const int eDecorationOverline     = nsStyle.TEXT_DECORATION_LINE_OVERLINE;
              const int eDecorationLineThrough  = nsStyle.TEXT_DECORATION_LINE_LINE_THROUGH;
              const int eDecorationBlink        = nsStyle.TEXT_DECORATION_LINE_BLINK;
              const int eDecorationPrefAnchors  = nsStyle.TEXT_DECORATION_LINE_PREF_ANCHORS;

              /*TODO: static*/ int32_t[] kTextDecorationKTable = {
            (int32_t)nsCSSKeyword.none,                   eDecorationNone,
            (int32_t)nsCSSKeyword.underline,              eDecorationUnderline,
            (int32_t)nsCSSKeyword.overline,               eDecorationOverline,
            (int32_t)nsCSSKeyword.line_through,           eDecorationLineThrough,
            (int32_t)nsCSSKeyword.blink,                  eDecorationBlink,
            (int32_t)nsCSSKeyword._moz_anchor_decoration, eDecorationPrefAnchors,
            (int32_t)nsCSSKeyword.UNKNOWN,-1
              };

              var value = new nsCSSValue();
              if (!ParseVariant(ref value, VARIANT_HK, kTextDecorationKTable)) {
            return false;
              }

              nsCSSValue blink = new nsCSSValue(), line = new nsCSSValue(), style = new nsCSSValue(), color = new nsCSSValue();
              switch (value.GetUnit()) {
            case nsCSSUnit.Enumerated: {
              // We shouldn't accept decoration line style and color via
              // text-decoration.
              color.SetIntValue(nsStyle.COLOR_MOZ_USE_TEXT_COLOR,
                                nsCSSUnit.Enumerated);
              style.SetIntValue(nsStyle.TEXT_DECORATION_STYLE_SOLID,
                                nsCSSUnit.Enumerated);

              int32_t intValue = value.GetIntValue();
              if (intValue == eDecorationNone) {
                blink.SetIntValue(nsStyle.TEXT_BLINK_NONE, nsCSSUnit.Enumerated);
                line.SetIntValue(nsStyle.TEXT_DECORATION_LINE_NONE,
                                 nsCSSUnit.Enumerated);
                break;
              }

              // look for more keywords
              var keyword = new nsCSSValue();
              int32_t index = 0;
              for (index = 0; index < 3; index++) {
                if (!ParseEnum(ref keyword, kTextDecorationKTable)) {
                  break;
                }
                int32_t newValue = keyword.GetIntValue();
                if (newValue == eDecorationNone || ((newValue & intValue) != 0)) {
                  // 'none' keyword in conjuction with others is not allowed, and
                  // duplicate keyword is not allowed.
                  return false;
                }
                intValue |= newValue;
              }

              blink.SetIntValue((intValue & eDecorationBlink) != 0 ?
                                  nsStyle.TEXT_BLINK_BLINK : nsStyle.TEXT_BLINK_NONE,
                                nsCSSUnit.Enumerated);
              line.SetIntValue((intValue & ~eDecorationBlink), nsCSSUnit.Enumerated);
              break;
            }
              goto default;
            default:
              blink = line = color = style = value;
              break;
              }

              AppendValue(nsCSSProperty.TextBlink, blink);
              AppendValue(nsCSSProperty.TextDecorationLine, line);
              AppendValue(nsCSSProperty.TextDecorationColor, color);
              AppendValue(nsCSSProperty.TextDecorationStyle, style);

              return true;
        }
Пример #20
0
 internal bool ParseMarks(ref nsCSSValue aValue)
 {
     if (ParseVariant(ref aValue, VARIANT_HK, nsCSSProps.kPageMarksKTable)) {
     if (nsCSSUnit.Enumerated == aValue.GetUnit()) {
       if (nsStyle.PAGE_MARKS_NONE != aValue.GetIntValue() &&
           false == CheckEndProperty()) {
         var second = new nsCSSValue();
         if (ParseEnum(ref second, nsCSSProps.kPageMarksKTable)) {
           // 'none' keyword in conjuction with others is not allowed
           if (nsStyle.PAGE_MARKS_NONE != second.GetIntValue()) {
             aValue.SetIntValue(aValue.GetIntValue() | second.GetIntValue(),
                                nsCSSUnit.Enumerated);
             return true;
           }
         }
         return false;
       }
     }
     return true;
       }
       return false;
 }
Пример #21
0
 static nsCSSValueList AppendValueToList(ref nsCSSValue aContainer,
                   nsCSSValueList aTail,
                   nsCSSValue aValue)
 {
     nsCSSValueList entry;
       if (aContainer.GetUnit() == nsCSSUnit.Null) {
     Debug.Assert(aTail == null, "should not have an entry");
     entry = aContainer.SetListValue();
       } else {
     Debug.Assert(aTail.mNext == null, "should not have a next entry");
     Debug.Assert(aContainer.GetUnit() == nsCSSUnit.List, "not a list");
     entry = new nsCSSValueList();
     aTail.mNext = entry;
       }
       entry.mValue = aValue;
       return entry;
 }
Пример #22
0
        // Note that callers passing VARIANT_CALC in aVariantMask will get
        // full-range parsing inside the calc() expression, and the code that
        // computes the calc will be required to clamp the resulting value to an
        // appropriate range.
        internal bool ParseOneOrLargerVariant(ref nsCSSValue aValue,
                                               int32_t aVariantMask,
                                               int32_t[] aKeywordTable)
        {
            // The variant mask must only contain non-numeric variants or the ones
              // that we specifically handle.
              Debug.Assert((aVariantMask & ~(VARIANT_ALL_NONNUMERIC |
                                              VARIANT_NUMBER |
                                              VARIANT_INTEGER)) == 0,
                            "need to update code below to handle additional variants");

              if (ParseVariant(ref aValue, aVariantMask, aKeywordTable)) {
            if (aValue.GetUnit() == nsCSSUnit.Integer) {
              if (aValue.GetIntValue() < 1) {
                UngetToken();
                return false;
              }
            } else if (nsCSSUnit.Number == aValue.GetUnit()) {
              if (aValue.GetFloatValue() < 1.0f) {
                UngetToken();
                return false;
              }
            }
            return true;
              }
              return false;
        }
Пример #23
0
 //typedef nsCSSValue input_type;
 //typedef nsCSSValue::Array input_array_type;
 public static CssUnit GetUnit(CssValue aValue)
 {
     return aValue.GetUnit();
 }
Пример #24
0
        //typedef nsCSSValue input_type;
        //typedef nsCSSValue::Array input_array_type;

        public static CssUnit GetUnit(CssValue aValue)
        {
            return(aValue.GetUnit());
        }