コード例 #1
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        internal bool ParseTransitionTimingFunctionValues(ref nsCSSValue aValue)
        {
            Debug.Assert(!mHavePushBack &&
                       mToken.mType == nsCSSTokenType.Function &&
                       mToken.mIdentStr.LowerCaseEqualsLiteral("cubic-bezier"),
                       "unexpected initial state");

              nsCSSValue[] val = new nsCSSValue[4];

              float x1 = 0, x2 = 0, y1 = 0, y2 = 0;
              if (!ParseTransitionTimingFunctionValueComponent(ref x1, ',', true) ||
              !ParseTransitionTimingFunctionValueComponent(ref y1, ',', false) ||
              !ParseTransitionTimingFunctionValueComponent(ref x2, ',', true) ||
              !ParseTransitionTimingFunctionValueComponent(ref y2, ')', false)) {
            return false;
              }

              val[0].SetFloatValue(x1, nsCSSUnit.Number);
              val[1].SetFloatValue(y1, nsCSSUnit.Number);
              val[2].SetFloatValue(x2, nsCSSUnit.Number);
              val[3].SetFloatValue(y2, nsCSSUnit.Number);

              aValue.SetArrayValue(val, nsCSSUnit.CubicBezier);

              return true;
        }
コード例 #2
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        bool ParseBackgroundPositionValues(ref nsCSSValue aOut,
                                                          bool aAcceptsInherit)
        {
            // css3-background allows positions to be defined as offsets
              // from an edge. There can be 2 keywords and 2 offsets given. These
              // four 'values' are stored in an array in the following order:
              // [keyword offset keyword offset]. If a keyword or offset isn't
              // parsed the value of the corresponding array element is set
              // to nsCSSUnit.Null by a call to nsCSSValue.Reset().
              if (aAcceptsInherit && ParseVariant(ref aOut, VARIANT_INHERIT, null)) {
            return true;
              }

              nsCSSValue[] value = new nsCSSValue[4];
              aOut.SetArrayValue(value, nsCSSUnit.Array);

              // The following clarifies organisation of the array.
              nsCSSValue xEdge   = value[0],
                     xOffset = value[1],
                     yEdge   = value[2],
                     yOffset = value[3];

              // Parse all the values into the array.
              uint32_t valueCount = 0;
              for (int32_t i = 0; i < 4; i++) {
            if (!ParseVariant(ref value[i], VARIANT_LPCALC | VARIANT_KEYWORD,
                              nsCSSProps.kBackgroundPositionKTable)) {
              break;
            }
            ++valueCount;
              }

              switch (valueCount) {
            case 4:
              // "If three or four values are given, then each <percentage> or <length>
              // represents an offset and must be preceded by a keyword, which specifies
              // from which edge the offset is given."
              if (nsCSSUnit.Enumerated != xEdge.GetUnit() ||
                  BG_CENTER == xEdge.GetIntValue() ||
                  nsCSSUnit.Enumerated == xOffset.GetUnit() ||
                  nsCSSUnit.Enumerated != yEdge.GetUnit() ||
                  BG_CENTER == yEdge.GetIntValue() ||
                  nsCSSUnit.Enumerated == yOffset.GetUnit()) {
                return false;
              }
              break;
            case 3:
              // "If three or four values are given, then each <percentage> or<length>
              // represents an offset and must be preceded by a keyword, which specifies
              // from which edge the offset is given." ... "If three values are given,
              // the missing offset is assumed to be zero."
              if (nsCSSUnit.Enumerated != value[1].GetUnit()) {
                // keyword offset keyword
                // Second value is non-keyword, thus first value must be a non-center
                // keyword.
                if (nsCSSUnit.Enumerated != value[0].GetUnit() ||
                    BG_CENTER == value[0].GetIntValue()) {
                  return false;
                }

                // Remaining value must be a keyword.
                if (nsCSSUnit.Enumerated != value[2].GetUnit()) {
                  return false;
                }

                yOffset.Reset(); // Everything else is in the correct position.
              } else if (nsCSSUnit.Enumerated != value[2].GetUnit()) {
                // keyword keyword offset
                // Third value is non-keyword, thus second value must be non-center
                // keyword.
                if (BG_CENTER == value[1].GetIntValue()) {
                  return false;
                }

                // Remaining value must be a keyword.
                if (nsCSSUnit.Enumerated != value[0].GetUnit()) {
                  return false;
                }

                // Move the values to the correct position in the array.
                value[3] = value[2]; // yOffset
                value[2] = value[1]; // yEdge
                value[1].Reset(); // xOffset
              } else {
                return false;
              }
              break;
            case 2:
              // "If two values are given and at least one value is not a keyword, then
              // the first value represents the horizontal position (or offset) and the
              // second represents the vertical position (or offset)"
              if (nsCSSUnit.Enumerated == value[0].GetUnit()) {
                if (nsCSSUnit.Enumerated == value[1].GetUnit()) {
                  // keyword keyword
                  value[2] = value[1]; // move yEdge to correct position
                  xOffset.Reset();
                  yOffset.Reset();
                } else {
                  // keyword offset
                  // First value must represent horizontal position.
                  if (((BG_TOP | BG_BOTTOM) & value[0].GetIntValue()) != 0) {
                    return false;
                  }
                  value[3] = value[1]; // move yOffset to correct position
                  xOffset.Reset();
                  yEdge.Reset();
                }
              } else {
                if (nsCSSUnit.Enumerated == value[1].GetUnit()) {
                  // offset keyword
                  // Second value must represent vertical position.
                  if (((BG_LEFT | BG_RIGHT) & value[1].GetIntValue()) != 0) {
                    return false;
                  }
                  value[2] = value[1]; // move yEdge to correct position
                  value[1] = value[0]; // move xOffset to correct position
                  xEdge.Reset();
                  yOffset.Reset();
                } else {
                  // offset offset
                  value[3] = value[1]; // move yOffset to correct position
                  value[1] = value[0]; // move xOffset to correct position
                  xEdge.Reset();
                  yEdge.Reset();
                }
              }
              break;
            case 1:
              // "If only one value is specified, the second value is assumed to be
              // center."
              if (nsCSSUnit.Enumerated == value[0].GetUnit()) {
                xOffset.Reset();
              } else {
                value[1] = value[0]; // move xOffset to correct position
                xEdge.Reset();
              }
              yEdge.SetIntValue(nsStyle.BG_POSITION_CENTER, nsCSSUnit.Enumerated);
              yOffset.Reset();
              break;
            default:
              return false;
              }

              // For compatibility with CSS2.1 code the edges can be unspecified.
              // Unspecified edges are recorded as NULL.
              Debug.Assert((nsCSSUnit.Enumerated == xEdge.GetUnit()  ||
                        nsCSSUnit.Null       == xEdge.GetUnit()) &&
                       (nsCSSUnit.Enumerated == yEdge.GetUnit()  ||
                        nsCSSUnit.Null       == yEdge.GetUnit()) &&
                        nsCSSUnit.Enumerated != xOffset.GetUnit()  &&
                        nsCSSUnit.Enumerated != yOffset.GetUnit(),
                        "Unexpected units");

              // Keywords in first and second pairs can not both be vertical or
              // horizontal keywords. (eg. left right, bottom top). Additionally,
              // non-center keyword can not be duplicated (eg. left left).
              int32_t xEdgeEnum =
                  xEdge.GetUnit() == nsCSSUnit.Enumerated ? xEdge.GetIntValue() : 0;
              int32_t yEdgeEnum =
                  yEdge.GetUnit() == nsCSSUnit.Enumerated ? yEdge.GetIntValue() : 0;
              if ((xEdgeEnum | yEdgeEnum) == (BG_LEFT | BG_RIGHT) ||
              (xEdgeEnum | yEdgeEnum) == (BG_TOP | BG_BOTTOM) ||
              ((xEdgeEnum & yEdgeEnum & ~BG_CENTER) != 0)) {
            return false;
              }

              // The values could be in an order that is different than expected.
              // eg. x contains vertical information, y contains horizontal information.
              // Swap if incorrect order.
              if (((xEdgeEnum & (BG_TOP | BG_BOTTOM)) != 0) ||
              ((yEdgeEnum & (BG_LEFT | BG_RIGHT)) != 0)) {
            nsCSSValue swapEdge = xEdge;
            nsCSSValue swapOffset = xOffset;
            xEdge = yEdge;
            xOffset = yOffset;
            yEdge = swapEdge;
            yOffset = swapOffset;
              }

              return true;
        }
コード例 #3
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        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;
        }
コード例 #4
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        internal bool ParseTransitionStepTimingFunctionValues(ref nsCSSValue aValue)
        {
            Debug.Assert(!mHavePushBack &&
                       mToken.mType == nsCSSTokenType.Function &&
                       mToken.mIdentStr.LowerCaseEqualsLiteral("steps"),
                       "unexpected initial state");

              nsCSSValue[] val = new nsCSSValue[2];

              if (!ParseOneOrLargerVariant(ref val[0], VARIANT_INTEGER, null)) {
            return false;
              }

              int32_t type = nsStyle.TRANSITION_TIMING_FUNCTION_STEP_END;
              if (ExpectSymbol(',', true)) {
            if (!GetToken(true)) {
              return false;
            }
            type = -1;
            if (mToken.mType == nsCSSTokenType.Ident) {
              if (mToken.mIdentStr.LowerCaseEqualsLiteral("start")) {
                type = nsStyle.TRANSITION_TIMING_FUNCTION_STEP_START;
              } else if (mToken.mIdentStr.LowerCaseEqualsLiteral("end")) {
                type = nsStyle.TRANSITION_TIMING_FUNCTION_STEP_END;
              }
            }
            if (type == -1) {
              UngetToken();
              return false;
            }
              }
              val[1].SetIntValue(type, nsCSSUnit.Enumerated);

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

              aValue.SetArrayValue(val, nsCSSUnit.Steps);
              return true;
        }
コード例 #5
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        // src: ( uri-src | local-src ) (',' ( uri-src | local-src ) )*
        // uri-src: uri [ 'format(' string ( ',' string )* ')' ]
        // local-src: 'local(' ( string | ident ) ')'
        internal bool ParseFontSrc(ref nsCSSValue aValue)
        {
            // could we maybe turn nsCSSValue[] into List<nsCSSValue>?
              var values = new List<nsCSSValue>();
              var cur = new nsCSSValue();
              for (;;) {
            if (!GetToken(true))
              break;

            if (mToken.mType == nsCSSTokenType.URL) {
              SetValueToURL(ref cur, mToken.mIdentStr);
              values.AppendElement(cur);
              if (!ParseFontSrcFormat(values))
                return false;

            } else if (mToken.mType == nsCSSTokenType.Function &&
                       mToken.mIdentStr.LowerCaseEqualsLiteral("local")) {
              // css3-fonts does not specify a formal grammar for local().
              // The text permits both unquoted identifiers and quoted
              // strings.  We resolve this ambiguity in the spec by
              // assuming that the appropriate production is a single
              // <family-name>, possibly surrounded by whitespace.

              var family = new StringBuilder();
              bool single = false;
              if (!ParseOneFamily(family, ref single)) {
                SkipUntil(')');
                return false;
              }
              if (!ExpectSymbol(')', true)) {
                SkipUntil(')');
                return false;
              }

              // the style parameters to the nsFont constructor are ignored,
              // because it's only being used to call EnumerateFamilies
              var font = new nsFont(family, 0, 0, 0, 0, 0, 0);
              var dat = new ExtractFirstFamilyData();

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

              cur.SetStringValue(dat.mFamilyName, nsCSSUnit.LocalFont);
              values.AppendElement(cur);
            } else {
              // We don't know what to do with this token; unget it and error out
              UngetToken();
              return false;
            }

            if (!ExpectSymbol(',', true))
              break;
              }

              if (values.Length() == 0)
            return false;

              nsCSSValue[] srcVals
            = new nsCSSValue[values.Length()];

              uint32_t i = 0;
              for (i = 0; i < values.Length(); i++)
            srcVals[i] = values[i];
              aValue.SetArrayValue(srcVals, nsCSSUnit.Array);
              return true;
        }
コード例 #6
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        /* Parses a function [ input of the form (a [, b]*) ] and stores it
         * as an nsCSSValue that holds a function of the form
         * function-name arg1 arg2 ... argN
         *
         * On error, the return value is false.
         *
         * @param aFunction The name of the function that we're reading.
         * @param aAllowedTypes An array of values corresponding to the legal
         *        types for each element in the function.  The zeroth element in the
         *        array corresponds to the first function parameter, etc.  The length
         *        of this array _must_ be greater than or equal to aMaxElems or the
         *        behavior is undefined.
         * @param aMinElems Minimum number of elements to read.  Reading fewer than
         *        this many elements will result in the function failing.
         * @param aMaxElems Maximum number of elements to read.  Reading more than
         *        this many elements will result in the function failing.
         * @param aValue (out) The value that was parsed.
         */
        internal bool ParseFunction(string aFunction,
                                     int32_t[] aAllowedTypes,
                                     uint16_t aMinElems, uint16_t aMaxElems,
                                     ref nsCSSValue aValue)
        {
            /* 2^16 - 2, so that if we have 2^16 - 2 transforms, we have 2^16 - 1
               * elements stored in the the nsCSSValue[].
               */
              const size_t MAX_ALLOWED_ELEMS = 0xFFFE;

              /* Make a copy of the function name, since the reference is _probably_ to
               * mToken.mIdentStr, which is going to get overwritten during the course of this
               * function.
               */
              string functionName = aFunction;

              /* Read in a list of values as an array, failing if we can't or if
               * it's out of bounds.
               */
              var foundValues = new List<nsCSSValue>();
              if (!ParseFunctionInternals(aAllowedTypes, aMinElems, aMaxElems,
                                      foundValues))
            return false;

              /* Now, convert this array into an nsCSSValue[] object.
               * We'll need N + 1 spots, one for the function name and the rest for the
               * arguments.  In case the user has given us more than 2^16 - 2 arguments,
               * we'll truncate them at 2^16 - 2 arguments.
               */
              uint16_t numElements = (uint16_t)(foundValues.Length() <= MAX_ALLOWED_ELEMS ?
                                  foundValues.Length() + 1 : MAX_ALLOWED_ELEMS);
              nsCSSValue[] convertedArray =
            new nsCSSValue[numElements];

              /* Copy things over. */
              convertedArray[0].SetStringValue(functionName, nsCSSUnit.Ident);
              for (uint16_t index = 0; index + 1 < numElements; ++index)
            convertedArray[index + 1] = foundValues[((size_t)(index))];

              /* Fill in the outparam value with the array. */
              aValue.SetArrayValue(convertedArray, nsCSSUnit.Function);

              /* Return it! */
              return true;
        }
コード例 #7
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        // font-ranges: urange ( ',' urange )*
        internal bool ParseFontRanges(ref nsCSSValue aValue)
        {
            var ranges = new List<uint32_t>();
              for (;;) {
            if (!GetToken(true))
              break;

            if (mToken.mType != nsCSSTokenType.URange) {
              UngetToken();
              break;
            }

            // An invalid range token is a parsing error, causing the entire
            // descriptor to be ignored.
            if (!mToken.mIntegerValid)
              return false;

            uint32_t low = mToken.mInteger;
            uint32_t high = mToken.mInteger2;

            // A range that descends, or a range that is entirely outside the
            // current range of Unicode (U+0-10FFFF) is ignored, but does not
            // invalidate the descriptor.  A range that straddles the high end
            // is clipped.
            if (low <= 0x10FFFF && low <= high) {
              if (high > 0x10FFFF)
                high = 0x10FFFF;

              ranges.AppendElement(low);
              ranges.AppendElement(high);
            }
            if (!ExpectSymbol(',', true))
              break;
              }

              if (ranges.Length() == 0)
            return false;

              nsCSSValue[] srcVals
            = new nsCSSValue[ranges.Length()];

              for (uint32_t i = 0; i < ranges.Length(); i++)
            srcVals[i].SetIntValue(ranges[i], nsCSSUnit.Integer);
              aValue.SetArrayValue(srcVals, nsCSSUnit.Array);
              return true;
        }
コード例 #8
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        internal bool ParseCounter(ref nsCSSValue aValue)
        {
            nsCSSUnit unit = (mToken.mIdentStr.LowerCaseEqualsLiteral("counter") ?
                            nsCSSUnit.Counter : nsCSSUnit.Counters);

              // A non-iterative for loop to break out when an error occurs.
              for (;;) {
            if (!GetToken(true)) {
              break;
            }
            if (nsCSSTokenType.Ident != mToken.mType) {
              UngetToken();
              break;
            }

            nsCSSValue[] val =
              new nsCSSValue[unit == nsCSSUnit.Counter ? 2 : 3];

            val[0].SetStringValue(mToken.mIdentStr, nsCSSUnit.Ident);

            if (nsCSSUnit.Counters == unit) {
              // must have a comma and then a separator string
              if (!ExpectSymbol(',', true) || !GetToken(true)) {
                break;
              }
              if (nsCSSTokenType.String != mToken.mType) {
                UngetToken();
                break;
              }
              val[1].SetStringValue(mToken.mIdentStr, nsCSSUnit.String);
            }

            // get optional type
            int32_t type = nsStyle.LIST_STYLE_DECIMAL;
            if (ExpectSymbol(',', true)) {
              if (!GetToken(true)) {
                break;
              }
              nsCSSKeyword keyword;
              if (nsCSSTokenType.Ident != mToken.mType ||
                  (keyword = nsCSSKeywords.LookupKeyword(mToken.mIdentStr)) ==
                    nsCSSKeyword.UNKNOWN ||
                  !nsCSSProps.FindKeyword(keyword, nsCSSProps.kListStyleKTable, ref type)) {
                UngetToken();
                break;
              }
            }

            int32_t typeItem = nsCSSUnit.Counters == unit ? 2 : 1;
            val[typeItem].SetIntValue(type, nsCSSUnit.Enumerated);

            if (!ExpectSymbol(')', true)) {
              break;
            }

            aValue.SetArrayValue(val, unit);
            return true;
              }

              SkipUntil(')');
              return false;
        }
コード例 #9
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        //  * If aVariantMask is VARIANT_NUMBER, this function parses the
        //    <number-multiplicative-expression> production.
        //  * If aVariantMask does not contain VARIANT_NUMBER, this function
        //    parses the <value-multiplicative-expression> 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.
        // It does so iteratively, but builds the correct recursive data
        // structure.
        // This function always consumes *trailing* whitespace when it returns
        // true; whether there was any such whitespace is returned in the
        // aHadFinalWS parameter.
        internal bool ParseCalcMultiplicativeExpression(ref nsCSSValue aValue,
                                                         ref int32_t aVariantMask,
                                                         ref bool aHadFinalWS)
        {
            Debug.Assert(aVariantMask != 0, "unexpected variant mask");
              bool gotValue = false; // already got the part with the unit
              bool afterDivision = false;

              nsCSSValue storage = aValue;
              for (;;) {
            int32_t variantMask = 0;
            if (afterDivision || gotValue) {
              variantMask = VARIANT_NUMBER;
            } else {
              variantMask = aVariantMask | VARIANT_NUMBER;
            }
            if (!ParseCalcTerm(ref storage, ref variantMask))
              return false;
            Debug.Assert(variantMask != 0,
                              "ParseCalcTerm did not set variantMask appropriately");

            if ((variantMask & VARIANT_NUMBER) != 0) {
              // Simplify the value immediately so we can check for division by
              // zero.
              var ops = new ReduceNumberCalcOps();
              float number = CommonUtil.ComputeCalc(storage, ops);
              if (number == 0.0 && afterDivision)
                return false;
              storage.SetFloatValue(number, nsCSSUnit.Number);
            } else {
              gotValue = true;

              if (storage != aValue) {
                // Simplify any numbers in the Times_L position (which are
                // not simplified by the check above).
                Debug.Assert(storage == aValue.GetArrayValue().Item(1),
                                  "unexpected relationship to current storage");
                nsCSSValue leftValue = aValue.GetArrayValue().Item(0);
                var ops = new ReduceNumberCalcOps();
                float number = CommonUtil.ComputeCalc(leftValue, ops);
                leftValue.SetFloatValue(number, nsCSSUnit.Number);
              }
            }

            bool hadWS = RequireWhitespace();
            if (!GetToken(false)) {
              aHadFinalWS = hadWS;
              break;
            }
            nsCSSUnit unit = 0;
            if (mToken.IsSymbol('*')) {
              unit = gotValue ? nsCSSUnit.CalcTimesR : nsCSSUnit.CalcTimesL;
              afterDivision = false;
            } else if (mToken.IsSymbol('/')) {
              unit = nsCSSUnit.CalcDivided;
              afterDivision = true;
            } else {
              UngetToken();
              aHadFinalWS = hadWS;
              break;
            }

            nsCSSValue[] arr = new nsCSSValue[2];
            arr[0] = aValue;
            storage = arr[1];
            aValue.SetArrayValue(arr, unit);
              }

              // Adjust aVariantMask (see comments above function) to reflect which
              // option we took.
              if ((aVariantMask & VARIANT_NUMBER) != 0) {
            if (gotValue) {
              aVariantMask &= ~((int32_t)(VARIANT_NUMBER));
            } else {
              aVariantMask = VARIANT_NUMBER;
            }
              } else {
            if (!gotValue) {
              // We had to find a value, but we didn't.
              return false;
            }
              }

              return true;
        }
コード例 #10
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        // We optimize away the <value-expression> production given that
        // ParseVariant consumes initial whitespace and we call
        // ExpectSymbol(')') with true for aSkipWS.
        //  * If aVariantMask is VARIANT_NUMBER, this function parses the
        //    <number-additive-expression> production.
        //  * If aVariantMask does not contain VARIANT_NUMBER, this function
        //    parses the <value-additive-expression> 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.
        // It does so iteratively, but builds the correct recursive
        // data structure.
        internal bool ParseCalcAdditiveExpression(ref nsCSSValue aValue,
                                                   ref int32_t aVariantMask)
        {
            Debug.Assert(aVariantMask != 0, "unexpected variant mask");
              nsCSSValue storage = aValue;
              for (;;) {
            bool haveWS = false;
            if (!ParseCalcMultiplicativeExpression(ref storage, ref aVariantMask, ref haveWS))
              return false;

            if (!haveWS || !GetToken(false))
              return true;
            nsCSSUnit unit = 0;
            if (mToken.IsSymbol('+')) {
              unit = nsCSSUnit.CalcPlus;
            } else if (mToken.IsSymbol('-')) {
              unit = nsCSSUnit.CalcMinus;
            } else {
              UngetToken();
              return true;
            }
            if (!RequireWhitespace())
              return false;

            nsCSSValue[] arr = new nsCSSValue[2];
            arr[0] = aValue;
            storage = arr[1];
            aValue.SetArrayValue(arr, unit);
              }
        }
コード例 #11
0
ファイル: nsCSSParser.conv.cs プロジェクト: jorik041/CsCss
        // Parse the top level of a calc() expression.
        internal bool ParseCalc(ref nsCSSValue aValue, int32_t aVariantMask)
        {
            // Parsing calc expressions requires, in a number of cases, looking
              // for a token that is *either* a value of the property or a number.
              // This can be done without lookahead when we assume that the property
              // values cannot themselves be numbers.
              Debug.Assert(!((aVariantMask & VARIANT_NUMBER) != 0), "unexpected variant mask");
              Debug.Assert(aVariantMask != 0, "unexpected variant mask");

              bool oldUnitlessLengthQuirk = mUnitlessLengthQuirk;
              mUnitlessLengthQuirk = false;

              // One-iteration loop so we can break to the error-handling case.
              do {
            // The toplevel of a calc() is always an nsCSSValue[] of length 1.
            nsCSSValue[] arr = new nsCSSValue[1];

            if (!ParseCalcAdditiveExpression(ref arr[0], ref aVariantMask))
              break;

            if (!ExpectSymbol(')', true))
              break;

            aValue.SetArrayValue(arr, nsCSSUnit.Calc);
            mUnitlessLengthQuirk = oldUnitlessLengthQuirk;
            return true;
              } while (false);

              SkipUntil(')');
              mUnitlessLengthQuirk = oldUnitlessLengthQuirk;
              return false;
        }