Rewrite handling of CSS system fonts to fix bugs in cascading and serialization. b=377947 r+sr=bzbarsky

This commit is contained in:
dbaron@dbaron.org 2007-06-12 11:28:56 -07:00
Родитель 01e481e23d
Коммит 17ccdad720
14 изменённых файлов: 269 добавлений и 97 удалений

Просмотреть файл

@ -472,6 +472,7 @@ nsCSSDeclaration::AppendCSSValueToString(nsCSSProperty aProperty,
case eCSSUnit_Initial: aResult.AppendLiteral("-moz-initial"); break;
case eCSSUnit_None: aResult.AppendLiteral("none"); break;
case eCSSUnit_Normal: aResult.AppendLiteral("normal"); break;
case eCSSUnit_System_Font: aResult.AppendLiteral("-moz-use-system-font"); break;
case eCSSUnit_String: break;
case eCSSUnit_URL: break;
@ -533,7 +534,18 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty,
}
// shorthands
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty) {
if (!mData->StorageFor(*p) &&
(!mImportantData || !mImportantData->StorageFor(*p)))
// We don't have all the properties in the shorthand.
if (*p != eCSSProperty__x_system_font)
return NS_OK;
}
// XXX What about checking the consistency of '!important'?
// XXX What about checking that we don't serialize inherit,
// -moz-initial, or other illegal values?
// XXXldb Can we share shorthand logic with ToString?
switch (aProperty) {
case eCSSProperty_margin:
@ -635,23 +647,38 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty,
break;
}
case eCSSProperty_font: {
if (AppendValueToString(eCSSProperty_font_style, aValue))
aValue.Append(PRUnichar(' '));
if (AppendValueToString(eCSSProperty_font_variant, aValue))
aValue.Append(PRUnichar(' '));
if (AppendValueToString(eCSSProperty_font_weight, aValue))
aValue.Append(PRUnichar(' '));
if (AppendValueToString(eCSSProperty_font_size, aValue)) {
nsAutoString tmp;
if (AppendValueToString(eCSSProperty_line_height, tmp)) {
aValue.Append(PRUnichar('/'));
aValue.Append(tmp);
}
aValue.Append(PRUnichar(' '));
if (!AppendValueToString(eCSSProperty_font_family, aValue))
aValue.Truncate();
nsCSSValue style, variant, weight, size, lh, family, systemFont;
GetValueOrImportantValue(eCSSProperty__x_system_font, systemFont);
GetValueOrImportantValue(eCSSProperty_font_style, style);
GetValueOrImportantValue(eCSSProperty_font_variant, variant);
GetValueOrImportantValue(eCSSProperty_font_weight, weight);
GetValueOrImportantValue(eCSSProperty_font_size, size);
GetValueOrImportantValue(eCSSProperty_line_height, lh);
GetValueOrImportantValue(eCSSProperty_font_family, family);
if (systemFont.GetUnit() != eCSSUnit_None &&
systemFont.GetUnit() != eCSSUnit_Null) {
AppendCSSValueToString(eCSSProperty__x_system_font, systemFont, aValue);
} else {
aValue.Truncate();
if (style.GetUnit() != eCSSUnit_Normal) {
AppendCSSValueToString(eCSSProperty_font_style, style, aValue);
aValue.Append(PRUnichar(' '));
}
if (variant.GetUnit() != eCSSUnit_Normal) {
AppendCSSValueToString(eCSSProperty_font_variant, variant, aValue);
aValue.Append(PRUnichar(' '));
}
if (weight.GetUnit() != eCSSUnit_Normal) {
AppendCSSValueToString(eCSSProperty_font_weight, weight, aValue);
aValue.Append(PRUnichar(' '));
}
AppendCSSValueToString(eCSSProperty_font_size, size, aValue);
if (lh.GetUnit() != eCSSUnit_Normal) {
aValue.Append(PRUnichar('/'));
AppendCSSValueToString(eCSSProperty_line_height, lh, aValue);
}
aValue.Append(PRUnichar(' '));
AppendCSSValueToString(eCSSProperty_font_family, family, aValue);
}
break;
}

Просмотреть файл

@ -173,6 +173,7 @@ CSS_KEY(-moz-thai, _moz_thai)
CSS_KEY(-moz-trad-chinese-formal, _moz_trad_chinese_formal)
CSS_KEY(-moz-trad-chinese-informal, _moz_trad_chinese_informal)
CSS_KEY(-moz-urdu, _moz_urdu)
CSS_KEY(-moz-use-system-font, _moz_use_system_font)
CSS_KEY(-moz-use-text-color, _moz_use_text_color)
CSS_KEY(-moz-visitedhyperlinktext, _moz_visitedhyperlinktext)
CSS_KEY(-moz-window, _moz_window)

Просмотреть файл

@ -169,6 +169,8 @@ protected:
public:
nsAutoParseCompoundProperty(CSSParserImpl* aParser) : mParser(aParser)
{
NS_ASSERTION(!aParser->IsParsingCompoundProperty(),
"already parsing compound property");
NS_ASSERTION(aParser, "Null parser?");
aParser->SetParsingCompoundProperty(PR_TRUE);
}
@ -3470,12 +3472,6 @@ CSSParserImpl::DoTransferTempData(nsCSSDeclaration* aDeclaration,
dest->~nsCSSValue();
memcpy(dest, source, sizeof(nsCSSValue));
new (source) nsCSSValue();
if (dest->GetUnit() == eCSSUnit_Null) {
// Some of our property parsers actually want to _clear_ properties in
// mData (eg the "font" shorthand parser does for system fonts). We've
// cleared the data; now clear the bit too.
mData.ClearPropertyBit(aPropID);
}
} break;
case eCSSType_Rect: {
@ -3549,6 +3545,7 @@ CSSParserImpl::DoTransferTempData(nsCSSDeclaration* aDeclaration,
#define VARIANT_INHERIT 0x020000 // H eCSSUnit_Initial, eCSSUnit_Inherit
#define VARIANT_NONE 0x040000 // O
#define VARIANT_NORMAL 0x080000 // M
#define VARIANT_SYSFONT 0x100000 // eCSSUnit_System_Font
// Common combinations of variants
#define VARIANT_AL (VARIANT_AUTO | VARIANT_LENGTH)
@ -3762,6 +3759,9 @@ PRBool CSSParserImpl::ParseVariant(nsresult& aErrorCode, nsCSSValue& aValue,
}
}
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 (eCSSKeyword_inherit == keyword) {
aValue.SetInheritValue();
return PR_TRUE;
@ -3783,6 +3783,13 @@ PRBool CSSParserImpl::ParseVariant(nsresult& aErrorCode, nsCSSValue& aValue,
return PR_TRUE;
}
}
if ((aVariantMask & VARIANT_SYSFONT) != 0) {
if (eCSSKeyword__moz_use_system_font == keyword &&
!IsParsingCompoundProperty()) {
aValue.SetSystemFontValue();
return PR_TRUE;
}
}
if ((aVariantMask & VARIANT_KEYWORD) != 0) {
PRInt32 value;
if (nsCSSProps::FindKeyword(keyword, aKeywordTable, value)) {
@ -4359,6 +4366,7 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode,
#endif
// Strip out properties we use internally.
case eCSSProperty__x_system_font:
case eCSSProperty_margin_end_value:
case eCSSProperty_margin_left_value:
case eCSSProperty_margin_right_value:
@ -4463,6 +4471,7 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
NS_ERROR("not a single value property");
return PR_FALSE;
case eCSSProperty__x_system_font:
case eCSSProperty_margin_left_ltr_source:
case eCSSProperty_margin_left_rtl_source:
case eCSSProperty_margin_right_ltr_source:
@ -4679,19 +4688,20 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_font_family:
return ParseFamily(aErrorCode, aValue);
case eCSSProperty_font_size:
return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HKLP,
return ParsePositiveVariant(aErrorCode, aValue,
VARIANT_HKLP | VARIANT_SYSFONT,
nsCSSProps::kFontSizeKTable);
case eCSSProperty_font_size_adjust:
return ParseVariant(aErrorCode, aValue, VARIANT_HON,
return ParseVariant(aErrorCode, aValue, VARIANT_HON | VARIANT_SYSFONT,
nsnull);
case eCSSProperty_font_stretch:
return ParseVariant(aErrorCode, aValue, VARIANT_HMK,
return ParseVariant(aErrorCode, aValue, VARIANT_HMK | VARIANT_SYSFONT,
nsCSSProps::kFontStretchKTable);
case eCSSProperty_font_style:
return ParseVariant(aErrorCode, aValue, VARIANT_HMK,
return ParseVariant(aErrorCode, aValue, VARIANT_HMK | VARIANT_SYSFONT,
nsCSSProps::kFontStyleKTable);
case eCSSProperty_font_variant:
return ParseVariant(aErrorCode, aValue, VARIANT_HMK,
return ParseVariant(aErrorCode, aValue, VARIANT_HMK | VARIANT_SYSFONT,
nsCSSProps::kFontVariantKTable);
case eCSSProperty_font_weight:
return ParseFontWeight(aErrorCode, aValue);
@ -4702,7 +4712,7 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
case eCSSProperty_word_spacing:
return ParseVariant(aErrorCode, aValue, VARIANT_HL | VARIANT_NORMAL, nsnull);
case eCSSProperty_line_height:
return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HLPN | VARIANT_NORMAL, nsnull);
return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HLPN | VARIANT_NORMAL | VARIANT_SYSFONT, nsnull);
case eCSSProperty_list_style_image:
return ParseVariant(aErrorCode, aValue, VARIANT_HUO, nsnull);
case eCSSProperty_list_style_position:
@ -5597,6 +5607,7 @@ PRBool CSSParserImpl::ParseFont(nsresult& aErrorCode)
if (ExpectEndProperty(aErrorCode, PR_TRUE)) {
if (eCSSUnit_Inherit == family.GetUnit() ||
eCSSUnit_Initial == family.GetUnit()) {
AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None));
AppendValue(eCSSProperty_font_family, family);
AppendValue(eCSSProperty_font_style, family);
AppendValue(eCSSProperty_font_variant, family);
@ -5607,22 +5618,16 @@ PRBool CSSParserImpl::ParseFont(nsresult& aErrorCode)
AppendValue(eCSSProperty_font_size_adjust, family);
}
else {
AppendValue(eCSSProperty_font_family, family); // keyword value overrides everything else
nsCSSValue empty;
// XXXbz this is actually _clearing_ the values for the following
// properties in mTempData, but setting the bit for them. We need that
// because we want to clear out the values in mData when all is said
// and done. See the code in TransferTempData that handles this. The
// end result is that mData always has its property bits set like it
// should, but mTempData can, in fact, have bits set for properties
// that are not set...
AppendValue(eCSSProperty_font_style, empty);
AppendValue(eCSSProperty_font_variant, empty);
AppendValue(eCSSProperty_font_weight, empty);
AppendValue(eCSSProperty_font_size, empty);
AppendValue(eCSSProperty_line_height, empty);
AppendValue(eCSSProperty_font_stretch, empty);
AppendValue(eCSSProperty_font_size_adjust, empty);
AppendValue(eCSSProperty__x_system_font, family);
nsCSSValue systemFont(eCSSUnit_System_Font);
AppendValue(eCSSProperty_font_family, systemFont);
AppendValue(eCSSProperty_font_style, systemFont);
AppendValue(eCSSProperty_font_variant, systemFont);
AppendValue(eCSSProperty_font_weight, systemFont);
AppendValue(eCSSProperty_font_size, systemFont);
AppendValue(eCSSProperty_line_height, systemFont);
AppendValue(eCSSProperty_font_stretch, systemFont);
AppendValue(eCSSProperty_font_size_adjust, systemFont);
}
return PR_TRUE;
}
@ -5670,9 +5675,11 @@ PRBool CSSParserImpl::ParseFont(nsresult& aErrorCode)
}
// Get final mandatory font-family
nsAutoParseCompoundProperty compound(this);
if (ParseFamily(aErrorCode, family)) {
if ((eCSSUnit_Inherit != family.GetUnit()) && (eCSSUnit_Initial != family.GetUnit()) &&
ExpectEndProperty(aErrorCode, PR_TRUE)) {
AppendValue(eCSSProperty__x_system_font, nsCSSValue(eCSSUnit_None));
AppendValue(eCSSProperty_font_family, family);
AppendValue(eCSSProperty_font_style, values[0]);
AppendValue(eCSSProperty_font_variant, values[1]);
@ -5689,7 +5696,7 @@ PRBool CSSParserImpl::ParseFont(nsresult& aErrorCode)
PRBool CSSParserImpl::ParseFontWeight(nsresult& aErrorCode, nsCSSValue& aValue)
{
if (ParseVariant(aErrorCode, aValue, VARIANT_HMKI, nsCSSProps::kFontWeightKTable)) {
if (ParseVariant(aErrorCode, aValue, VARIANT_HMKI | VARIANT_SYSFONT, nsCSSProps::kFontWeightKTable)) {
if (eCSSUnit_Integer == aValue.GetUnit()) { // ensure unit value
PRInt32 intValue = aValue.GetIntValue();
if ((100 <= intValue) &&
@ -5722,10 +5729,15 @@ PRBool CSSParserImpl::ParseFamily(nsresult& aErrorCode, nsCSSValue& aValue)
aValue.SetInheritValue();
return PR_TRUE;
}
else if (keyword == eCSSKeyword__moz_initial) {
if (keyword == eCSSKeyword__moz_initial) {
aValue.SetInitialValue();
return PR_TRUE;
}
if (keyword == eCSSKeyword__moz_use_system_font &&
!IsParsingCompoundProperty()) {
aValue.SetSystemFontValue();
return PR_TRUE;
}
}
else {
family.Append(PRUnichar(','));

Просмотреть файл

@ -269,6 +269,9 @@ CSS_PROP_OUTLINE(-moz-outline-radius-topleft, _moz_outline_radius_topLeft, MozOu
CSS_PROP_OUTLINE(-moz-outline-radius-topright, _moz_outline_radius_topRight, MozOutlineRadiusTopright, Margin, mOutlineRadius.mRight, eCSSType_Value, nsnull)
CSS_PROP_OUTLINE(-moz-outline-radius-bottomleft, _moz_outline_radius_bottomLeft, MozOutlineRadiusBottomleft, Margin, mOutlineRadius.mLeft, eCSSType_Value, nsnull)
CSS_PROP_OUTLINE(-moz-outline-radius-bottomright, _moz_outline_radius_bottomRight, MozOutlineRadiusBottomright, Margin, mOutlineRadius.mBottom, eCSSType_Value, nsnull)
#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
CSS_PROP_FONT(-x-system-font, _x_system_font, X, Font, mSystemFont, eCSSType_Value, kFontKTable)
#endif
CSS_PROP_BACKENDONLY(azimuth, azimuth, Azimuth, Aural, mAzimuth, eCSSType_Value, kAzimuthKTable)
CSS_PROP_SHORTHAND(background, background, Background)
CSS_PROP_BACKGROUND(background-attachment, background_attachment, BackgroundAttachment, Color, mBackAttachment, eCSSType_Value, kBackgroundAttachmentKTable)
@ -329,7 +332,7 @@ CSS_PROP_TABLEBORDER(empty-cells, empty_cells, EmptyCells, Table, mEmptyCells, e
CSS_PROP_DISPLAY(float, float, CssFloat, Display, mFloat, eCSSType_Value, kFloatKTable)
CSS_PROP_BORDER(-moz-float-edge, float_edge, MozFloatEdge, Margin, mFloatEdge, eCSSType_Value, kFloatEdgeKTable) // XXX bug 3935
CSS_PROP_SHORTHAND(font, font, Font)
CSS_PROP_FONT(font-family, font_family, FontFamily, Font, mFamily, eCSSType_Value, kFontKTable)
CSS_PROP_FONT(font-family, font_family, FontFamily, Font, mFamily, eCSSType_Value, nsnull)
CSS_PROP_FONT(font-size, font_size, FontSize, Font, mSize, eCSSType_Value, kFontSizeKTable)
CSS_PROP_FONT(font-size-adjust, font_size_adjust, FontSizeAdjust, Font, mSizeAdjust, eCSSType_Value, nsnull)
CSS_PROP_BACKENDONLY(font-stretch, font_stretch, FontStretch, Font, mStretch, eCSSType_Value, kFontStretchKTable)

Просмотреть файл

@ -1333,6 +1333,7 @@ static const nsCSSProperty gFontSubpropTable[] = {
eCSSProperty_line_height,
eCSSProperty_font_size_adjust, // XXX Added LDB.
eCSSProperty_font_stretch, // XXX Added LDB.
eCSSProperty__x_system_font,
eCSSProperty_UNKNOWN
};

Просмотреть файл

@ -202,6 +202,7 @@ struct nsCSSFont : public nsCSSStruct {
nsCSSFont(const nsCSSFont& aCopy);
~nsCSSFont(void);
nsCSSValue mSystemFont;
nsCSSValue mFamily;
nsCSSValue mStyle;
nsCSSValue mVariant;

Просмотреть файл

@ -349,6 +349,12 @@ void nsCSSValue::SetNormalValue()
mUnit = eCSSUnit_Normal;
}
void nsCSSValue::SetSystemFontValue()
{
Reset();
mUnit = eCSSUnit_System_Font;
}
void nsCSSValue::StartImageLoad(nsIDocument* aDocument, PRBool aIsBGImage) const
{
NS_PRECONDITION(eCSSUnit_URL == mUnit, "Not a URL value!");

Просмотреть файл

@ -62,6 +62,7 @@ enum nsCSSUnit {
eCSSUnit_Initial = 3, // (n/a) value is default UA value
eCSSUnit_None = 4, // (n/a) value is none
eCSSUnit_Normal = 5, // (n/a) value is normal (algorithmic, different than auto)
eCSSUnit_System_Font = 6, // (n/a) value is -moz-use-system-font
eCSSUnit_String = 10, // (PRUnichar*) a string value
eCSSUnit_Attr = 11, // (PRUnichar*) a attr(string) value
eCSSUnit_Array = 20, // (nsCSSValue::Array*) a list of values
@ -135,8 +136,8 @@ public:
explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
: mUnit(aUnit)
{
NS_ASSERTION(aUnit <= eCSSUnit_Normal, "not a valueless unit");
if (aUnit > eCSSUnit_Normal) {
NS_ASSERTION(aUnit <= eCSSUnit_System_Font, "not a valueless unit");
if (aUnit > eCSSUnit_System_Font) {
mUnit = eCSSUnit_Null;
}
mValue.mInt = 0;
@ -275,6 +276,7 @@ public:
NS_HIDDEN_(void) SetInitialValue();
NS_HIDDEN_(void) SetNoneValue();
NS_HIDDEN_(void) SetNormalValue();
NS_HIDDEN_(void) SetSystemFontValue();
NS_HIDDEN_(void) StartImageLoad(nsIDocument* aDocument,
PRBool aIsBGImage = PR_FALSE)
const; // Not really const, but pretending

Просмотреть файл

@ -1911,24 +1911,11 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
const nsFont* defaultVariableFont =
aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID);
// font-family: string list, enum, inherit
if (eCSSUnit_String == aFontData.mFamily.GetUnit()) {
// set the correct font if we are using DocumentFonts OR we are overriding for XUL
// MJA: bug 31816
if (!aIsGeneric) {
// only bother appending fallback fonts if this isn't a fallback generic font itself
if (!aFont->mFont.name.IsEmpty())
aFont->mFont.name.Append((PRUnichar)',');
// XXXldb Should this name be quoted?
aFont->mFont.name.Append(aDefaultFont.name);
}
aFont->mFont.familyNameQuirks =
(aPresContext->CompatibilityMode() == eCompatibility_NavQuirks &&
aFontData.mFamilyFromHTML);
}
else if (eCSSUnit_Enumerated == aFontData.mFamily.GetUnit()) {
// -moz-system-font: enum (never inherit!)
nsFont systemFont;
if (eCSSUnit_Enumerated == aFontData.mSystemFont.GetUnit()) {
nsSystemFontID sysID;
switch (aFontData.mFamily.GetIntValue()) {
switch (aFontData.mSystemFont.GetIntValue()) {
// If you add fonts to this list, you need to also patch the list
// in CheckFontCallback (also in this file).
case NS_STYLE_FONT_CAPTION: sysID = eSystemFont_Caption; break; // css2
@ -1950,17 +1937,14 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
}
// GetSystemFont sets the font face but not necessarily the size
aFont->mFont.size = defaultVariableFont->size;
// XXX Or at least it used to -- no longer true for thebes. Maybe
// it should be again, though.
systemFont.size = defaultVariableFont->size;
if (NS_FAILED(aPresContext->DeviceContext()->GetSystemFont(sysID,
&aFont->mFont))) {
aFont->mFont.name = defaultVariableFont->name;
&systemFont))) {
systemFont.name = defaultVariableFont->name;
}
// this becomes our cascading size
aFont->mSize = aFont->mFont.size =
nsStyleFont::ZoomText(aPresContext, aFont->mFont.size);
aFont->mFont.familyNameQuirks = PR_FALSE;
// XXXldb All of this platform-specific stuff should be in the
// nsIDeviceContext implementations, not here.
@ -1983,20 +1967,50 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
case eSystemFont_Button:
case eSystemFont_List:
// Assumption: system defined font is proportional
aFont->mSize = nsStyleFont::ZoomText(aPresContext,
PR_MAX(defaultVariableFont->size - aPresContext->PointsToAppUnits(2), 0));
systemFont.size =
PR_MAX(defaultVariableFont->size - aPresContext->PointsToAppUnits(2), 0);
break;
}
#endif
} else {
// In case somebody explicitly used -moz-use-system-font.
systemFont = *defaultVariableFont;
}
// font-family: string list, enum, inherit
NS_ASSERTION(eCSSUnit_Enumerated != aFontData.mFamily.GetUnit(),
"system fonts should not be in mFamily anymore");
if (eCSSUnit_String == aFontData.mFamily.GetUnit()) {
// set the correct font if we are using DocumentFonts OR we are overriding for XUL
// MJA: bug 31816
if (!aIsGeneric) {
// only bother appending fallback fonts if this isn't a fallback generic font itself
if (!aFont->mFont.name.IsEmpty())
aFont->mFont.name.Append((PRUnichar)',');
// XXXldb Should this name be quoted?
aFont->mFont.name.Append(aDefaultFont.name);
}
aFont->mFont.familyNameQuirks =
(aPresContext->CompatibilityMode() == eCompatibility_NavQuirks &&
aFontData.mFamilyFromHTML);
aFont->mFont.systemFont = PR_FALSE;
}
else if (eCSSUnit_System_Font == aFontData.mFamily.GetUnit()) {
aFont->mFont.name = systemFont.name;
aFont->mFont.familyNameQuirks = PR_FALSE;
aFont->mFont.systemFont = PR_TRUE;
}
else if (eCSSUnit_Inherit == aFontData.mFamily.GetUnit()) {
aInherited = PR_TRUE;
aFont->mFont.name = aParentFont->mFont.name;
aFont->mFont.familyNameQuirks = aParentFont->mFont.familyNameQuirks;
aFont->mFont.systemFont = aParentFont->mFont.systemFont;
}
else if (eCSSUnit_Initial == aFontData.mFamily.GetUnit()) {
aFont->mFont.name = defaultVariableFont->name;
aFont->mFont.familyNameQuirks = PR_FALSE;
aFont->mFont.systemFont = defaultVariableFont->systemFont;
}
// font-style: enum, normal, inherit
@ -2006,6 +2020,9 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
else if (eCSSUnit_Normal == aFontData.mStyle.GetUnit()) {
aFont->mFont.style = NS_STYLE_FONT_STYLE_NORMAL;
}
else if (eCSSUnit_System_Font == aFontData.mStyle.GetUnit()) {
aFont->mFont.style = systemFont.style;
}
else if (eCSSUnit_Inherit == aFontData.mStyle.GetUnit()) {
aInherited = PR_TRUE;
aFont->mFont.style = aParentFont->mFont.style;
@ -2021,6 +2038,9 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
else if (eCSSUnit_Normal == aFontData.mVariant.GetUnit()) {
aFont->mFont.variant = NS_STYLE_FONT_VARIANT_NORMAL;
}
else if (eCSSUnit_System_Font == aFontData.mVariant.GetUnit()) {
aFont->mFont.variant = systemFont.variant;
}
else if (eCSSUnit_Inherit == aFontData.mVariant.GetUnit()) {
aInherited = PR_TRUE;
aFont->mFont.variant = aParentFont->mFont.variant;
@ -2050,6 +2070,9 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
else if (eCSSUnit_Normal == aFontData.mWeight.GetUnit()) {
aFont->mFont.weight = NS_STYLE_FONT_WEIGHT_NORMAL;
}
else if (eCSSUnit_System_Font == aFontData.mWeight.GetUnit()) {
aFont->mFont.weight = systemFont.weight;
}
else if (eCSSUnit_Inherit == aFontData.mWeight.GetUnit()) {
aInherited = PR_TRUE;
aFont->mFont.weight = aParentFont->mFont.weight;
@ -2110,6 +2133,11 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
aFontData.mSize.GetPercentValue());
zoom = PR_FALSE;
}
else if (eCSSUnit_System_Font == aFontData.mSize.GetUnit()) {
// this becomes our cascading size
aFont->mSize = systemFont.size;
zoom = PR_TRUE;
}
else if (eCSSUnit_Inherit == aFontData.mSize.GetUnit()) {
aInherited = PR_TRUE;
aFont->mSize = aParentFont->mSize;
@ -2137,6 +2165,9 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, nsStyleContext* aContext,
else if (eCSSUnit_None == aFontData.mSizeAdjust.GetUnit()) {
aFont->mFont.sizeAdjust = 0.0f;
}
else if (eCSSUnit_System_Font == aFontData.mSizeAdjust.GetUnit()) {
aFont->mFont.sizeAdjust = systemFont.sizeAdjust;
}
else if (eCSSUnit_Inherit == aFontData.mSizeAdjust.GetUnit()) {
aInherited = PR_TRUE;
aFont->mFont.sizeAdjust = aParentFont->mFont.sizeAdjust;
@ -2357,7 +2388,8 @@ nsRuleNode::ComputeTextData(nsStyleStruct* aStartStruct,
nscoord(float(aContext->GetStyleFont()->mFont.size) *
textData.mLineHeight.GetPercentValue()));
}
else if (eCSSUnit_Initial == textData.mLineHeight.GetUnit()) {
else if (eCSSUnit_Initial == textData.mLineHeight.GetUnit() ||
eCSSUnit_System_Font == textData.mLineHeight.GetUnit()) {
text->mLineHeight.SetNormalValue();
}
else {

Просмотреть файл

@ -112,6 +112,7 @@ const char* gShorthandPropertiesWithDOMProp[] = {
const char *gInaccessibleProperties[] = {
// Don't print the properties that aren't accepted by the parser, per
// CSSParserImpl::ParseProperty
"-x-system-font",
"margin-end-value",
"margin-left-value",
"margin-right-value",

Просмотреть файл

@ -72,6 +72,7 @@ _TEST_FILES = test_bug221428.html \
test_bug365932.html \
test_bug372770.html \
test_bug373293.html \
test_bug377947.html \
test_bug379440.html \
test_bug379741.html \
test_bug383075.html \

Просмотреть файл

@ -65,7 +65,7 @@ for (var i = 0; i <= 100; ++i) {
// Bug 372783 means this doesn't round-trip quite right
todo(style1.color == color1,
"Inline style color roundtripping failed at opacity " + i);
todo(style1.background == color2,
todo(style1.backgroundColor == color2,
"Inline style background roundtripping failed at opacity " + i);
todo(style2.color == color2,
"Rule style color roundtripping failed at opacity " + i);
@ -77,7 +77,7 @@ for (var i = 0; i <= 100; ++i) {
is(style1.color, color1,
"Inline style color roundtripping failed at opacity " + i);
is(style1.background, color2,
is(style1.backgroundColor, color2,
"Inline style background roundtripping failed at opacity " + i);
is(style2.color, color2,
"Rule style color roundtripping failed at opacity " + i);

Просмотреть файл

@ -0,0 +1,91 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=377947
-->
<head>
<title>Test for Bug 377947</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=377947">Mozilla Bug 377947</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 377947 **/
/*
* In particular, test that CSSStyleDeclaration.getPropertyValue doesn't
* return values for shorthands when some of the subproperties are not
* specified (a change that wasn't all that related to the main point of
* the bug). And also test that the internal system-font property added
* in bug 377947 doesn't interfere with that.
*/
var s = document.getElementById("display").style;
is(s.getPropertyValue("list-style"), "",
"list-style shorthand should start off empty");
s.listStyleType="disc";
s.listStyleImage="none";
is(s.getPropertyValue("list-style"), "",
"list-style shorthand should be empty when some subproperties specified");
s.listStylePosition="inside";
isnot(s.getPropertyValue("list-style"), "",
"list-style shorthand should produce value when all subproperties set");
s.removeProperty("list-style");
is(s.getPropertyValue("list-style"), "",
"list-style shorthand be empty after removal");
s.listStyle="none";
isnot(s.getPropertyValue("list-style"), "",
"list-style shorthand should produce value when shorthand set");
s.removeProperty("list-style");
is(s.getPropertyValue("list-style"), "",
"list-style shorthand be empty after removal");
is(s.getPropertyValue("font"), "",
"font shorthand should start off empty");
var all_but_one = {
"font-family": "serif",
"font-style": "normal",
"font-variant": "normal",
"font-weight": "bold",
"font-size": "small",
"font-size-adjust": "0.45",
"font-stretch": "normal"
};
for (var prop in all_but_one) {
s.setProperty(prop, all_but_one[prop], "");
}
is(s.getPropertyValue("font"), "",
"font shorthand should be empty when some subproperties specified");
s.setProperty("line-height", "1.5", "");
isnot(s.getPropertyValue("font"), "",
"font shorthand should produce value when all subproperties set");
s.removeProperty("font");
is(s.getPropertyValue("font"), "",
"font shorthand be empty after removal");
s.font="medium serif";
isnot(s.getPropertyValue("font"), "",
"font shorthand should produce value when shorthand set");
s.removeProperty("font");
is(s.getPropertyValue("font"), "",
"font shorthand be empty after removal");
s.font="menu";
isnot(s.getPropertyValue("font"), "",
"font shorthand should produce value when shorthand (system font) set");
s.removeProperty("font");
is(s.getPropertyValue("font"), "",
"font shorthand be empty after removal");
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -69,9 +69,14 @@ var gNotAccepted = {
"list-style": [ "none disc outside" ],
};
var gSpecialFont = [
"caption", "icon", "menu", "message-box", "small-caption", "status-bar"
];
var gSystemFont = {
"caption": true,
"icon": true,
"menu": true,
"message-box": true,
"small-caption": true,
"status-bar": true,
};
var gBadCompute = {
// output wrapped around to positive, in exponential notation
@ -89,9 +94,6 @@ function xfail_accepted(property, value)
gNotAccepted[property].indexOf(value) != -1)
return true;
if (property == "font" && gSpecialFont.indexOf(value) != -1)
return true;
return false;
}
@ -101,10 +103,6 @@ function xfail_accepted_split(property, subprop, value)
gNotAccepted[property].indexOf(value) != -1)
return true;
if (property == "font" && subprop != "font-family" &&
gSpecialFont.indexOf(value) != -1)
return true;
return false;
}
@ -155,13 +153,6 @@ function xfail_idserparse_compute(property, value)
function xfail_idsersplitparse_compute(property, subprop, value, step1subcomp)
{
// These failures depend on what the system fonts actually are,
// since they show up in computed style but not serialization!
if (property == "font" &&
gSpecialFont.indexOf(value) != -1 &&
gCSSProperties[subprop].initial_values.indexOf(step1subcomp) == -1)
return true;
return false;
}
@ -247,7 +238,10 @@ function test_property(property)
property + ": " + value + "'");
}
if ("subproperties" in info) {
if ("subproperties" in info &&
// Using setProperty over subproperties is not sufficient for
// system fonts, since the shorthand does more than its parts.
(property != "font" || !(value in gSystemFont))) {
gDeclaration.removeProperty(property);
for (idx in info.subproperties) {
var subprop = info.subproperties[idx];