internal void SetBorderImageInitialValues() { // border-image-source: none var source = new nsCSSValue(); source.SetNoneValue(); AppendValue(nsCSSProperty.BorderImageSource, source); // border-image-slice: 100% var sliceBoxValue = new nsCSSValue(); nsCSSRect sliceBox = sliceBoxValue.SetRectValue(); sliceBox.SetAllSidesTo(new nsCSSValue(1.0f, nsCSSUnit.Percent)); var slice = new nsCSSValue(); nsCSSValueList sliceList = slice.SetListValue(); sliceList.mValue = sliceBoxValue; AppendValue(nsCSSProperty.BorderImageSlice, slice); // border-image-width: 1 var width = new nsCSSValue(); nsCSSRect widthBox = width.SetRectValue(); widthBox.SetAllSidesTo(new nsCSSValue(1.0f, nsCSSUnit.Number)); AppendValue(nsCSSProperty.BorderImageWidth, width); // border-image-outset: 0 var outset = new nsCSSValue(); nsCSSRect outsetBox = outset.SetRectValue(); outsetBox.SetAllSidesTo(new nsCSSValue(0.0f, nsCSSUnit.Number)); AppendValue(nsCSSProperty.BorderImageOutset, outset); // border-image-repeat: repeat var repeat = new nsCSSValue(); var repeatPair = new nsCSSValuePair(); repeatPair.SetBothValuesTo(new nsCSSValue(nsStyle.BORDER_IMAGE_REPEAT_STRETCH, nsCSSUnit.Enumerated)); repeat.SetPairValue(repeatPair); AppendValue(nsCSSProperty.BorderImageRepeat, repeat); }
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; }
// Assigns to aValue iff it returns true. internal bool ParseVariant(ref nsCSSValue aValue, int32_t aVariantMask, int32_t[] aKeywordTable) { Debug.Assert(!(mHashlessColorQuirk && ((aVariantMask & VARIANT_COLOR) != 0)) || !((aVariantMask & VARIANT_NUMBER) != 0), "can't distinguish colors from numbers"); Debug.Assert(!(mHashlessColorQuirk && ((aVariantMask & VARIANT_COLOR) != 0)) || !(mUnitlessLengthQuirk && ((aVariantMask & VARIANT_LENGTH) != 0)), "can't distinguish colors from lengths"); Debug.Assert(!(mUnitlessLengthQuirk && ((aVariantMask & VARIANT_LENGTH) != 0)) || !((aVariantMask & VARIANT_NUMBER) != 0), "can't distinguish lengths from numbers"); Debug.Assert(!((aVariantMask & VARIANT_IDENTIFIER) != 0) || !((aVariantMask & VARIANT_IDENTIFIER_NO_INHERIT) != 0), "must not set both VARIANT_IDENTIFIER and VARIANT_IDENTIFIER_NO_INHERIT"); if (!GetToken(true)) { return false; } nsCSSToken tk = mToken; if (((aVariantMask & (VARIANT_AHK | VARIANT_NORMAL | VARIANT_NONE | VARIANT_ALL)) != 0) && (nsCSSTokenType.Ident == tk.mType)) { nsCSSKeyword keyword = nsCSSKeywords.LookupKeyword(tk.mIdentStr); if (nsCSSKeyword.UNKNOWN < keyword) { // known keyword if ((aVariantMask & VARIANT_AUTO) != 0) { if (nsCSSKeyword.auto == keyword) { aValue.SetAutoValue(); return true; } } if ((aVariantMask & VARIANT_INHERIT) != 0) { // XXX Should we check IsParsingCompoundProperty, or do all // callers handle it? (Not all callers set it, though, since // they want the quirks that are disabled by setting it.) if (nsCSSKeyword.inherit == keyword) { aValue.SetInheritValue(); return true; } else if (nsCSSKeyword._moz_initial == keyword || nsCSSKeyword.initial == keyword) { // anything that can inherit can also take an initial val. aValue.SetInitialValue(); return true; } } if ((aVariantMask & VARIANT_NONE) != 0) { if (nsCSSKeyword.none == keyword) { aValue.SetNoneValue(); return true; } } if ((aVariantMask & VARIANT_ALL) != 0) { if (nsCSSKeyword.all == keyword) { aValue.SetAllValue(); return true; } } if ((aVariantMask & VARIANT_NORMAL) != 0) { if (nsCSSKeyword.normal == keyword) { aValue.SetNormalValue(); return true; } } if ((aVariantMask & VARIANT_SYSFONT) != 0) { if (nsCSSKeyword._moz_use_system_font == keyword && !IsParsingCompoundProperty()) { aValue.SetSystemFontValue(); return true; } } if ((aVariantMask & VARIANT_KEYWORD) != 0) { int32_t value = 0; if (nsCSSProps.FindKeyword(keyword, aKeywordTable, ref value)) { aValue.SetIntValue(value, nsCSSUnit.Enumerated); return true; } } } } // Check VARIANT_NUMBER and VARIANT_INTEGER before VARIANT_LENGTH or // VARIANT_ZERO_ANGLE. if (((aVariantMask & VARIANT_NUMBER) != 0) && (nsCSSTokenType.Number == tk.mType)) { aValue.SetFloatValue(tk.mNumber, nsCSSUnit.Number); return true; } if (((aVariantMask & VARIANT_INTEGER) != 0) && (nsCSSTokenType.Number == tk.mType) && tk.mIntegerValid) { aValue.SetIntValue(tk.mInteger, nsCSSUnit.Integer); return true; } if (((aVariantMask & (VARIANT_LENGTH | VARIANT_ANGLE | VARIANT_FREQUENCY | VARIANT_TIME)) != 0 && nsCSSTokenType.Dimension == tk.mType) || ((aVariantMask & (VARIANT_LENGTH | VARIANT_ZERO_ANGLE)) != 0 && nsCSSTokenType.Number == tk.mType && tk.mNumber == 0.0f)) { if (((aVariantMask & VARIANT_POSITIVE_DIMENSION) != 0 && tk.mNumber <= 0.0) || ((aVariantMask & VARIANT_NONNEGATIVE_DIMENSION) != 0 && tk.mNumber < 0.0)) { UngetToken(); return false; } if (TranslateDimension(ref aValue, aVariantMask, tk.mNumber, tk.mIdentStr)) { return true; } // Put the token back; we didn't parse it, so we shouldn't consume it UngetToken(); return false; } if (((aVariantMask & VARIANT_PERCENT) != 0) && (nsCSSTokenType.Percentage == tk.mType)) { aValue.SetPercentValue(tk.mNumber); return true; } if (mUnitlessLengthQuirk) { // NONSTANDARD: Nav interprets unitless numbers as px if (((aVariantMask & VARIANT_LENGTH) != 0) && (nsCSSTokenType.Number == tk.mType)) { aValue.SetFloatValue(tk.mNumber, nsCSSUnit.Pixel); return true; } } if (IsSVGMode() && !IsParsingCompoundProperty()) { // STANDARD: SVG Spec states that lengths and coordinates can be unitless // in which case they default to user-units (1 px = 1 user unit) if (((aVariantMask & VARIANT_LENGTH) != 0) && (nsCSSTokenType.Number == tk.mType)) { aValue.SetFloatValue(tk.mNumber, nsCSSUnit.Pixel); return true; } } if (((aVariantMask & VARIANT_URL) != 0) && nsCSSTokenType.URL == tk.mType) { SetValueToURL(ref aValue, tk.mIdentStr); return true; } if ((aVariantMask & VARIANT_GRADIENT) != 0 && nsCSSTokenType.Function == tk.mType) { // a generated gradient string tmp = tk.mIdentStr; bool isLegacy = false; if (StringBeginsWith(tmp, "-moz-")) { tmp = tmp.Substring(5); isLegacy = true; } bool isRepeating = false; if (StringBeginsWith(tmp, "repeating-")) { tmp = tmp.Substring(10); isRepeating = true; } if (tmp.LowerCaseEqualsLiteral("linear-gradient")) { return ParseLinearGradient(ref aValue, isRepeating, isLegacy); } if (tmp.LowerCaseEqualsLiteral("radial-gradient")) { return ParseRadialGradient(ref aValue, isRepeating, isLegacy); } } if ((aVariantMask & VARIANT_IMAGE_RECT) != 0 && nsCSSTokenType.Function == tk.mType && tk.mIdentStr.LowerCaseEqualsLiteral("-moz-image-rect")) { return ParseImageRect(ref aValue); } if ((aVariantMask & VARIANT_ELEMENT) != 0 && nsCSSTokenType.Function == tk.mType && tk.mIdentStr.LowerCaseEqualsLiteral("-moz-element")) { return ParseElement(ref aValue); } if ((aVariantMask & VARIANT_COLOR) != 0) { if (mHashlessColorQuirk || // NONSTANDARD: Nav interprets 'xxyyzz' values even without '#' prefix (nsCSSTokenType.ID == tk.mType) || (nsCSSTokenType.Hash == tk.mType) || (nsCSSTokenType.Ident == tk.mType) || ((nsCSSTokenType.Function == tk.mType) && (tk.mIdentStr.LowerCaseEqualsLiteral("rgb") || tk.mIdentStr.LowerCaseEqualsLiteral("hsl") || tk.mIdentStr.LowerCaseEqualsLiteral("-moz-rgba") || tk.mIdentStr.LowerCaseEqualsLiteral("-moz-hsla") || tk.mIdentStr.LowerCaseEqualsLiteral("rgba") || tk.mIdentStr.LowerCaseEqualsLiteral("hsla")))) { // Put token back so that parse color can get it UngetToken(); if (ParseColor(ref aValue)) { return true; } return false; } } if (((aVariantMask & VARIANT_STRING) != 0) && (nsCSSTokenType.String == tk.mType)) { string buffer; buffer = tk.mIdentStr; aValue.SetStringValue(buffer, nsCSSUnit.String); return true; } if (((aVariantMask & (VARIANT_IDENTIFIER | VARIANT_IDENTIFIER_NO_INHERIT)) != 0) && (nsCSSTokenType.Ident == tk.mType) && ((aVariantMask & VARIANT_IDENTIFIER) != 0 || !(tk.mIdentStr.LowerCaseEqualsLiteral("inherit") || tk.mIdentStr.LowerCaseEqualsLiteral("initial")))) { aValue.SetStringValue(tk.mIdentStr, nsCSSUnit.Ident); return true; } if (((aVariantMask & VARIANT_COUNTER) != 0) && (nsCSSTokenType.Function == tk.mType) && (tk.mIdentStr.LowerCaseEqualsLiteral("counter") || tk.mIdentStr.LowerCaseEqualsLiteral("counters"))) { return ParseCounter(ref aValue); } if (((aVariantMask & VARIANT_ATTR) != 0) && (nsCSSTokenType.Function == tk.mType) && tk.mIdentStr.LowerCaseEqualsLiteral("attr")) { if (!ParseAttr(ref aValue)) { SkipUntil(')'); return false; } return true; } if (((aVariantMask & VARIANT_TIMING_FUNCTION) != 0) && (nsCSSTokenType.Function == tk.mType)) { if (tk.mIdentStr.LowerCaseEqualsLiteral("cubic-bezier")) { if (!ParseTransitionTimingFunctionValues(ref aValue)) { SkipUntil(')'); return false; } return true; } if (tk.mIdentStr.LowerCaseEqualsLiteral("steps")) { if (!ParseTransitionStepTimingFunctionValues(ref aValue)) { SkipUntil(')'); return false; } return true; } } if (((aVariantMask & VARIANT_CALC) != 0) && (nsCSSTokenType.Function == tk.mType) && (tk.mIdentStr.LowerCaseEqualsLiteral("calc") || tk.mIdentStr.LowerCaseEqualsLiteral("-moz-calc"))) { // calc() currently allows only lengths and percents inside it. return ParseCalc(ref aValue, aVariantMask & VARIANT_LP); } UngetToken(); return false; }
internal bool ParseBorderSide(nsCSSProperty[] aPropIDs, bool aSetAllSides) { uint32_t numProps = 3; var values = new nsCSSValue[numProps]; int32_t found = ParseChoice(ref values, aPropIDs, numProps); if ((found < 1) || (false == ExpectEndProperty())) { return false; } if ((found & 1) == 0) { // Provide default border-width values[0].SetIntValue(nsStyle.BORDER_WIDTH_MEDIUM, nsCSSUnit.Enumerated); } if ((found & 2) == 0) { // Provide default border-style values[1].SetIntValue(nsStyle.BORDER_STYLE_NONE, nsCSSUnit.Enumerated); } if ((found & 4) == 0) { // text color will be used values[2].SetIntValue(nsStyle.COLOR_MOZ_USE_TEXT_COLOR, nsCSSUnit.Enumerated); } if (aSetAllSides) { /*TODO: static*/ nsCSSProperty[] kBorderSources = { nsCSSProperty.BorderLeftColorLtrSource, nsCSSProperty.BorderLeftColorRtlSource, nsCSSProperty.BorderRightColorLtrSource, nsCSSProperty.BorderRightColorRtlSource, nsCSSProperty.BorderLeftStyleLtrSource, nsCSSProperty.BorderLeftStyleRtlSource, nsCSSProperty.BorderRightStyleLtrSource, nsCSSProperty.BorderRightStyleRtlSource, nsCSSProperty.BorderLeftWidthLtrSource, nsCSSProperty.BorderLeftWidthRtlSource, nsCSSProperty.BorderRightWidthLtrSource, nsCSSProperty.BorderRightWidthRtlSource, nsCSSProperty.Unknown }; InitBoxPropsAsPhysical(kBorderSources); // Parsing "border" shorthand; set all four sides to the same thing for (int32_t index = 0; index < 4; index++) { Debug.Assert(numProps == 3, "This code needs updating"); AppendValue(kBorderWidthIDs[index], values[0]); AppendValue(kBorderStyleIDs[index], values[1]); AppendValue(kBorderColorIDs[index], values[2]); } /*TODO: static*/ nsCSSProperty[] kBorderColorsProps = { nsCSSProperty.BorderTopColors, nsCSSProperty.BorderRightColors, nsCSSProperty.BorderBottomColors, nsCSSProperty.BorderLeftColors }; // Set the other properties that the border shorthand sets to their // initial values. var extraValue = new nsCSSValue(); switch (values[0].GetUnit()) { case nsCSSUnit.Inherit: case nsCSSUnit.Initial: extraValue = values[0]; // Set value of border-image properties to initial/inherit AppendValue(nsCSSProperty.BorderImageSource, extraValue); AppendValue(nsCSSProperty.BorderImageSlice, extraValue); AppendValue(nsCSSProperty.BorderImageWidth, extraValue); AppendValue(nsCSSProperty.BorderImageOutset, extraValue); AppendValue(nsCSSProperty.BorderImageRepeat, extraValue); break; default: extraValue.SetNoneValue(); SetBorderImageInitialValues(); break; } for (Side side = nsStyle.SIDE_TOP; side <= nsStyle.SIDE_LEFT; side++) { AppendValue(kBorderColorsProps[(int)side], extraValue); } } else { // Just set our one side for (int32_t index = 0; index < numProps; index++) { AppendValue(aPropIDs[(int)index], values[index]); } } return true; }