// The types to pass to ParseColorComponent. These correspond to the // various datatypes that can go within rgb(). internal bool ParseColor(ref nsCSSValue aValue) { if (!GetToken(true)) { { if (!mSuppressErrors) mReporter.ReportUnexpected("PEColorEOF"); }; return false; } nsCSSToken tk = mToken; var rgba = new nscolor(); switch (tk.mType) { case nsCSSTokenType.ID: case nsCSSTokenType.Hash: // #xxyyzz if (nscolor.HexToRGB(tk.mIdentStr, ref rgba)) { aValue.SetColorValue(rgba); return true; } break; case nsCSSTokenType.Ident: if (nscolor.ColorNameToRGB(tk.mIdentStr, ref rgba)) { aValue.SetStringValue(tk.mIdentStr, nsCSSUnit.Ident); return true; } else { nsCSSKeyword keyword = nsCSSKeywords.LookupKeyword(tk.mIdentStr); if (nsCSSKeyword.UNKNOWN < keyword) { // known keyword int32_t value = 0; if (nsCSSProps.FindKeyword(keyword, nsCSSProps.kColorKTable, ref value)) { aValue.SetIntValue(value, nsCSSUnit.EnumColor); return true; } } } break; case nsCSSTokenType.Function: if (mToken.mIdentStr.LowerCaseEqualsLiteral("rgb")) { // rgb ( component , component , component ) uint8_t r = 0, g = 0, b = 0; int32_t type = COLOR_TYPE_UNKNOWN; if (ParseColorComponent(ref r, ref type, ',') && ParseColorComponent(ref g, ref type, ',') && ParseColorComponent(ref b, ref type, ')')) { aValue.SetColorValue(nscolor.RGB(r,g,b)); return true; } SkipUntil(')'); return false; } else if (mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-rgba") || mToken.mIdentStr.LowerCaseEqualsLiteral("rgba")) { // rgba ( component , component , component , opacity ) uint8_t r = 0, g = 0, b = 0, a = 0; int32_t type = COLOR_TYPE_UNKNOWN; if (ParseColorComponent(ref r, ref type, ',') && ParseColorComponent(ref g, ref type, ',') && ParseColorComponent(ref b, ref type, ',') && ParseColorOpacity(ref a)) { aValue.SetColorValue(nscolor.RGBA(r, g, b, a)); return true; } SkipUntil(')'); return false; } else if (mToken.mIdentStr.LowerCaseEqualsLiteral("hsl")) { // hsl ( hue , saturation , lightness ) // "hue" is a number, "saturation" and "lightness" are percentages. if (ParseHSLColor(ref rgba, ')')) { aValue.SetColorValue(rgba); return true; } SkipUntil(')'); return false; } else if (mToken.mIdentStr.LowerCaseEqualsLiteral("-moz-hsla") || mToken.mIdentStr.LowerCaseEqualsLiteral("hsla")) { // hsla ( hue , saturation , lightness , opacity ) // "hue" is a number, "saturation" and "lightness" are percentages, // "opacity" is a number. uint8_t a = 0; if (ParseHSLColor(ref rgba, ',') && ParseColorOpacity(ref a)) { aValue.SetColorValue(nscolor.RGBA(rgba.R, rgba.G, rgba.B, a)); return true; } SkipUntil(')'); return false; } break; default: break; } // try 'xxyyzz' without '#' prefix for compatibility with IE and Nav4x (bug 23236 and 45804) // TODO support hashless colors // It's not a color { if (!mSuppressErrors) mReporter.ReportUnexpected("PEColorNotColor", mToken); }; UngetToken(); return false; }
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; } }