diff --git a/content/base/src/nsRuleNode.cpp b/content/base/src/nsRuleNode.cpp index 859041a81fd9..aee9309ad058 100644 --- a/content/base/src/nsRuleNode.cpp +++ b/content/base/src/nsRuleNode.cpp @@ -577,35 +577,43 @@ struct StructCheckData { CheckCallbackFn callback; }; -static void -ExamineRectProperties(const nsCSSRect* aRect, - PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) + +/** + * @param aValue the value being examined + * @param aSpecifiedCount to be incremented by one if the value is specified + * @param aInherited to be incremented by one if the value is set to inherit + */ +inline void +ExamineCSSValue(const nsCSSValue& aValue, + PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) { - if (!aRect) - return; - - if (eCSSUnit_Null != aRect->mLeft.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mLeft.GetUnit()) - aInheritedCount++; + if (aValue.GetUnit() != eCSSUnit_Null) { + ++aSpecifiedCount; + if (aValue.GetUnit() == eCSSUnit_Inherit) { + ++aInheritedCount; + } } +} - if (eCSSUnit_Null != aRect->mTop.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mTop.GetUnit()) - aInheritedCount++; - } +static void +ExamineCSSValuePair(const nsCSSValuePair* aValuePair, + PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) +{ + NS_PRECONDITION(aValuePair, "Must have a value pair"); + + ExamineCSSValue(aValuePair->mXValue, aSpecifiedCount, aInheritedCount); + ExamineCSSValue(aValuePair->mYValue, aSpecifiedCount, aInheritedCount); +} - if (eCSSUnit_Null != aRect->mRight.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mRight.GetUnit()) - aInheritedCount++; - } +static void +ExamineCSSRect(const nsCSSRect* aRect, + PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) +{ + NS_PRECONDITION(aRect, "Must have a rect"); - if (eCSSUnit_Null != aRect->mBottom.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mBottom.GetUnit()) - aInheritedCount++; + NS_FOR_CSS_SIDES(side) { + ExamineCSSValue(aRect->*(nsCSSRect::sides[side]), + aSpecifiedCount, aInheritedCount); } } @@ -840,6 +848,13 @@ RectAtOffset(const nsRuleDataStruct& aRuleDataStruct, size_t aOffset) NS_REINTERPRET_CAST(const char*, &aRuleDataStruct) + aOffset); } +inline const nsCSSValuePair* +ValuePairAtOffset(const nsRuleDataStruct& aRuleDataStruct, size_t aOffset) +{ + return NS_REINTERPRET_CAST(const nsCSSValuePair*, + NS_REINTERPRET_CAST(const char*, &aRuleDataStruct) + aOffset); +} + inline const nsCSSValueList* ValueListAtOffset(const nsRuleDataStruct& aRuleDataStruct, size_t aOffset) { @@ -893,24 +908,23 @@ nsRuleNode::CheckSpecifiedProperties(const nsStyleStructID aSID, switch (prop->type) { case eCSSType_Value: - { - ++total; - const nsCSSValue& value = ValueAtOffset(aRuleDataStruct, prop->offset); - if (eCSSUnit_Null != value.GetUnit()) { - ++specified; - if (eCSSUnit_Inherit == value.GetUnit()) { - ++inherited; - } - } - } + ++total; + ExamineCSSValue(ValueAtOffset(aRuleDataStruct, prop->offset), + specified, inherited); break; case eCSSType_Rect: total += 4; - ExamineRectProperties(RectAtOffset(aRuleDataStruct, prop->offset), - specified, inherited); + ExamineCSSRect(RectAtOffset(aRuleDataStruct, prop->offset), + specified, inherited); break; + case eCSSType_ValuePair: + total += 2; + ExamineCSSValuePair(ValuePairAtOffset(aRuleDataStruct, prop->offset), + specified, inherited); + break; + case eCSSType_ValueList: { ++total; @@ -3827,18 +3841,18 @@ nsRuleNode::ComputeTableBorderData(nsStyleStruct* aStartStruct, nsStyleCoord coord; // border-spacing-x: length, inherit - if (SetCoord(tableData.mBorderSpacingX, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { + if (SetCoord(tableData.mBorderSpacing.mXValue, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { table->mBorderSpacingX = coord.GetCoordValue(); } - else if (eCSSUnit_Inherit == tableData.mBorderSpacingX.GetUnit()) { + else if (eCSSUnit_Inherit == tableData.mBorderSpacing.mXValue.GetUnit()) { inherited = PR_TRUE; table->mBorderSpacingX = parentTable->mBorderSpacingX; } // border-spacing-y: length, inherit - if (SetCoord(tableData.mBorderSpacingY, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { + if (SetCoord(tableData.mBorderSpacing.mYValue, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { table->mBorderSpacingY = coord.GetCoordValue(); } - else if (eCSSUnit_Inherit == tableData.mBorderSpacingY.GetUnit()) { + else if (eCSSUnit_Inherit == tableData.mBorderSpacing.mYValue.GetUnit()) { inherited = PR_TRUE; table->mBorderSpacingY = parentTable->mBorderSpacingY; } diff --git a/content/html/content/src/nsHTMLTableElement.cpp b/content/html/content/src/nsHTMLTableElement.cpp index 897e8eca5ea4..b7de668566d5 100644 --- a/content/html/content/src/nsHTMLTableElement.cpp +++ b/content/html/content/src/nsHTMLTableElement.cpp @@ -1085,17 +1085,17 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes, // cellspacing const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::cellspacing); if (value && value->Type() == nsAttrValue::eInteger) { - if (aData->mTableData->mBorderSpacingX.GetUnit() == eCSSUnit_Null) - aData->mTableData->mBorderSpacingX.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); - if (aData->mTableData->mBorderSpacingY.GetUnit() == eCSSUnit_Null) - aData->mTableData->mBorderSpacingY.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); + if (aData->mTableData->mBorderSpacing.mXValue.GetUnit() == eCSSUnit_Null) + aData->mTableData->mBorderSpacing.mXValue.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); + if (aData->mTableData->mBorderSpacing.mYValue.GetUnit() == eCSSUnit_Null) + aData->mTableData->mBorderSpacing.mYValue.SetFloatValue((float)value->GetIntegerValue(), eCSSUnit_Pixel); } else if (value && value->Type() == nsAttrValue::ePercent && eCompatibility_NavQuirks == mode) { // in quirks mode, treat a % cellspacing value a pixel value. - if (aData->mTableData->mBorderSpacingX.GetUnit() == eCSSUnit_Null) - aData->mTableData->mBorderSpacingX.SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel); - if (aData->mTableData->mBorderSpacingY.GetUnit() == eCSSUnit_Null) - aData->mTableData->mBorderSpacingY.SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel); + if (aData->mTableData->mBorderSpacing.mXValue.GetUnit() == eCSSUnit_Null) + aData->mTableData->mBorderSpacing.mXValue.SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel); + if (aData->mTableData->mBorderSpacing.mYValue.GetUnit() == eCSSUnit_Null) + aData->mTableData->mBorderSpacing.mYValue.SetFloatValue(100.0f * value->GetPercentValue(), eCSSUnit_Pixel); } } } diff --git a/content/html/style/src/nsCSSDataBlock.cpp b/content/html/style/src/nsCSSDataBlock.cpp index c54e613855cb..d33701220938 100644 --- a/content/html/style/src/nsCSSDataBlock.cpp +++ b/content/html/style/src/nsCSSDataBlock.cpp @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -66,6 +67,11 @@ struct CDBRectStorage { }; +struct CDBValuePairStorage { + nsCSSProperty property; + nsCSSValuePair value; +}; + struct CDBPointerStorage { nsCSSProperty property; void *value; @@ -74,6 +80,7 @@ struct CDBPointerStorage { enum { CDBValueStorage_advance = sizeof(CDBValueStorage), CDBRectStorage_advance = sizeof(CDBRectStorage), + CDBValuePairStorage_advance = sizeof(CDBValuePairStorage), // round up using the closest estimate we can get of the alignment // requirements of nsCSSValue: CDBPointerStorage_advance = PR_ROUNDUP(sizeof(CDBPointerStorage), @@ -112,6 +119,14 @@ inline const nsCSSRect* RectAtCursor(const char *aCursor) { return & NS_REINTERPRET_CAST(const CDBRectStorage*, aCursor)->value; } +inline nsCSSValuePair* ValuePairAtCursor(char *aCursor) { + return & NS_REINTERPRET_CAST(CDBValuePairStorage*, aCursor)->value; +} + +inline const nsCSSValuePair* ValuePairAtCursor(const char *aCursor) { + return & NS_REINTERPRET_CAST(const CDBValuePairStorage*, aCursor)->value; +} + inline void*& PointerAtCursor(char *aCursor) { return NS_REINTERPRET_CAST(CDBPointerStorage*, aCursor)->value; } @@ -215,6 +230,18 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + nsCSSValuePair* target = NS_STATIC_CAST(nsCSSValuePair*, prop); + if (target->mXValue.GetUnit() == eCSSUnit_Null) + target->mXValue = val->mXValue; + if (target->mYValue.GetUnit() == eCSSUnit_Null) + target->mYValue = val->mYValue; + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: if (iProp == eCSSProperty_content) { for (nsCSSValueList* l = ValueListAtCursor(cursor); @@ -246,6 +273,10 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -285,6 +316,9 @@ nsCSSCompressedDataBlock::StorageFor(nsCSSProperty aProperty) const case eCSSType_Rect: { return RectAtCursor(cursor); } + case eCSSType_ValuePair: { + return ValuePairAtCursor(cursor); + } case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -302,6 +336,10 @@ nsCSSCompressedDataBlock::StorageFor(nsCSSProperty aProperty) const cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -352,6 +390,16 @@ nsCSSCompressedDataBlock::Clone() const result_cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + nsCSSValuePair* result_val = ValuePairAtCursor(result_cursor); + new (result_val) nsCSSValuePair(*val); + cursor += CDBValuePairStorage_advance; + result_cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -421,6 +469,14 @@ nsCSSCompressedDataBlock::Destroy() cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + val->~nsCSSValuePair(); + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: { nsCSSValueList* val = ValueListAtCursor(cursor); NS_ASSERTION(val, "oops"); @@ -532,6 +588,14 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock, cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + memcpy(prop, val, sizeof(nsCSSValuePair)); + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -594,6 +658,14 @@ nsCSSExpandedDataBlock::ComputeSize() } } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + if (val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null) { + increment = CDBValuePairStorage_advance; + } + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -692,6 +764,20 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, } } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + if (val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null) { + CDBValuePairStorage *storage = + NS_REINTERPRET_CAST(CDBValuePairStorage*, cursor); + storage->property = iProp; + memcpy(&storage->value, val, sizeof(nsCSSValuePair)); + new (val) nsCSSValuePair(); + cursor += CDBValuePairStorage_advance; + present = PR_TRUE; + } + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -769,6 +855,12 @@ nsCSSExpandedDataBlock::ClearProperty(nsCSSProperty aPropID) val->Reset(); } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + val->mXValue.Reset(); + val->mYValue.Reset(); + } break; + case eCSSType_ValueList: { nsCSSValueList*& val = *NS_STATIC_CAST(nsCSSValueList**, prop); if (val) { @@ -837,6 +929,14 @@ nsCSSExpandedDataBlock::DoAssertInitialState() "not initial state"); } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + NS_ASSERTION(val->mXValue.GetUnit() == eCSSUnit_Null, + "not initial state"); + NS_ASSERTION(val->mYValue.GetUnit() == eCSSUnit_Null, + "not initial state"); + } break; + case eCSSType_ValueList: { nsCSSValueList* val = *NS_STATIC_CAST(nsCSSValueList**, prop); NS_ASSERTION(val == nsnull, "not initial state"); diff --git a/content/html/style/src/nsCSSDeclaration.cpp b/content/html/style/src/nsCSSDeclaration.cpp index 46a5b2eec2b3..671b7c3c3489 100644 --- a/content/html/style/src/nsCSSDeclaration.cpp +++ b/content/html/style/src/nsCSSDeclaration.cpp @@ -40,6 +40,7 @@ #include "nsString.h" #include "nsIAtom.h" #include "nsUnicharUtils.h" +#include "nsReadableUtils.h" #include "nsCRT.h" #include "nsCSSProps.h" #include "nsUnitConversion.h" @@ -214,6 +215,15 @@ PRBool nsCSSDeclaration::AppendValueToString(nsCSSProperty aProperty, nsAString& aResult.Append(PRUnichar(')')); } } break; + case eCSSType_ValuePair: { + const nsCSSValuePair *pair = NS_STATIC_CAST(const nsCSSValuePair*, storage); + AppendCSSValueToString(aProperty, pair->mXValue, aResult); + if (pair->mYValue != pair->mXValue) { + // Only output a Y value if it's different from the X value + aResult.Append(PRUnichar(' ')); + AppendCSSValueToString(aProperty, pair->mYValue, aResult); + } + } break; case eCSSType_ValueList: { const nsCSSValueList* val = *NS_STATIC_CAST(nsCSSValueList*const*, storage); @@ -364,18 +374,6 @@ PRBool nsCSSDeclaration::AppendCSSValueToString(nsCSSProperty aProperty, const n AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, NS_STYLE_AZIMUTH_BEHIND), aResult); } } - else if (eCSSProperty_play_during_flags == aProperty) { - PRInt32 intValue = aValue.GetIntValue(); - if ((NS_STYLE_PLAY_DURING_MIX & intValue) != 0) { - AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, NS_STYLE_PLAY_DURING_MIX), aResult); - } - if ((NS_STYLE_PLAY_DURING_REPEAT & intValue) != 0) { - if (NS_STYLE_PLAY_DURING_REPEAT != intValue) { - aResult.Append(PRUnichar(' ')); - } - AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, NS_STYLE_PLAY_DURING_REPEAT), aResult); - } - } else if (eCSSProperty_marks == aProperty) { PRInt32 intValue = aValue.GetIntValue(); if ((NS_STYLE_PAGE_MARKS_CROP & intValue) != 0) { @@ -493,7 +491,9 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, aValue.Truncate(0); // simple properties are easy. - if (!nsCSSProps::IsShorthand(aProperty)) { + if (!nsCSSProps::IsShorthand(aProperty) && + // play-during is not a real shorthand, but is special... + aProperty != eCSSProperty_play_during) { AppendValueToString(aProperty, aValue); return NS_OK; } @@ -584,16 +584,6 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, } break; } - case eCSSProperty_border_spacing: - if (AppendValueToString(eCSSProperty_border_x_spacing, aValue)) { - aValue.Append(PRUnichar(' ')); -#ifdef DEBUG - PRBool check = -#endif - AppendValueToString(eCSSProperty_border_y_spacing, aValue); - NS_ASSERTION(check, "we parsed half of border-spacing"); - } - break; case eCSSProperty_cue: { if (AppendValueToString(eCSSProperty_cue_after, aValue)) { aValue.Append(PRUnichar(' ')); @@ -646,14 +636,6 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, } break; } - case eCSSProperty_size: { - if (AppendValueToString(eCSSProperty_size_width, aValue)) { - aValue.Append(PRUnichar(' ')); - if (!AppendValueToString(eCSSProperty_size_height, aValue)) - aValue.Truncate(); - } - break; - } case eCSSProperty_background_position: { if (AppendValueToString(eCSSProperty_background_x_position, aValue)) { aValue.Append(PRUnichar(' ')); @@ -666,11 +648,32 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, break; } case eCSSProperty_play_during: { - if (AppendValueToString(eCSSProperty_play_during_uri, aValue)) { - nsAutoString tmp; - if (AppendValueToString(eCSSProperty_play_during_flags, tmp)) { - aValue.Append(PRUnichar(' ')); - aValue.Append(tmp); + nsCSSCompressedDataBlock *data = + GetValueIsImportant(eCSSProperty_play_during) ? mImportantData : mData; + const void *storage = data->StorageFor(eCSSProperty_play_during); + if (!storage) { + break; + } + NS_ASSERTION(nsCSSProps::kTypeTable[eCSSProperty_play_during] == + eCSSType_ValuePair, + "Someone changed the storage type of play-during!"); + const nsCSSValuePair *pair = NS_STATIC_CAST(const nsCSSValuePair*, storage); + AppendCSSValueToString(aProperty, pair->mXValue, aValue); + if (pair->mYValue != eCSSUnit_Null) { + aValue.Append(PRUnichar(' ')); + PRInt32 intValue = pair->mYValue.GetIntValue(); + if ((NS_STYLE_PLAY_DURING_MIX & intValue) != 0) { + AppendUTF8toUTF16(nsCSSProps::LookupPropertyValue(aProperty, + NS_STYLE_PLAY_DURING_MIX), + aValue); + } + if ((NS_STYLE_PLAY_DURING_REPEAT & intValue) != 0) { + if (NS_STYLE_PLAY_DURING_REPEAT != intValue) { + aValue.Append(PRUnichar(' ')); + } + AppendUTF8toUTF16(nsCSSProps::LookupPropertyValue(aProperty, + NS_STYLE_PLAY_DURING_REPEAT), + aValue); } } break; diff --git a/content/html/style/src/nsCSSParser.cpp b/content/html/style/src/nsCSSParser.cpp index 4f39655dab6d..fd4e766ee153 100644 --- a/content/html/style/src/nsCSSParser.cpp +++ b/content/html/style/src/nsCSSParser.cpp @@ -3223,6 +3223,16 @@ CSSParserImpl::DoTransferTempData(nsCSSDeclaration* aDeclaration, new (source) nsCSSRect(); } break; + case eCSSType_ValuePair: { + nsCSSValuePair *source = NS_STATIC_CAST(nsCSSValuePair*, v_source); + nsCSSValuePair *dest = NS_STATIC_CAST(nsCSSValuePair*, v_dest); + if (*source != *dest) + *aChanged = PR_TRUE; + dest->~nsCSSValuePair(); + memcpy(dest, source, sizeof(nsCSSValuePair)); + new (source) nsCSSValuePair(); + } break; + case eCSSType_ValueList: { nsCSSValueList **source = NS_STATIC_CAST(nsCSSValueList**, v_source); nsCSSValueList **dest = NS_STATIC_CAST(nsCSSValueList**, v_dest); @@ -4060,12 +4070,6 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, // by compound property parsing routines (e.g. "background-position"). case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: - case eCSSProperty_border_x_spacing: - case eCSSProperty_border_y_spacing: - case eCSSProperty_play_during_flags: - case eCSSProperty_play_during_uri: - case eCSSProperty_size_height: - case eCSSProperty_size_width: case eCSSProperty_margin_end_value: case eCSSProperty_margin_left_value: case eCSSProperty_margin_right_value: @@ -4179,12 +4183,6 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, NS_ERROR("not a single value property"); return PR_FALSE; - case eCSSProperty_border_x_spacing: - case eCSSProperty_border_y_spacing: - case eCSSProperty_play_during_flags: - case eCSSProperty_play_during_uri: - case eCSSProperty_size_height: - case eCSSProperty_size_width: case eCSSProperty_margin_left_ltr_source: case eCSSProperty_margin_left_rtl_source: case eCSSProperty_margin_right_ltr_source: @@ -4874,8 +4872,9 @@ PRBool CSSParserImpl::ParseBorderSpacing(nsresult& aErrorCode) if (ParsePositiveVariant(aErrorCode, yValue, VARIANT_LENGTH, nsnull)) { // We have two numbers if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_border_x_spacing, xValue); - AppendValue(eCSSProperty_border_y_spacing, yValue); + mTempData.mTable.mBorderSpacing.mXValue = xValue; + mTempData.mTable.mBorderSpacing.mYValue = yValue; + mTempData.SetPropertyBit(eCSSProperty_border_spacing); return PR_TRUE; } return PR_FALSE; @@ -4885,8 +4884,8 @@ PRBool CSSParserImpl::ParseBorderSpacing(nsresult& aErrorCode) // We have one length which is the horizontal spacing. Create a value for // the vertical spacing which is equal if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_border_x_spacing, xValue); - AppendValue(eCSSProperty_border_y_spacing, xValue); + mTempData.mTable.mBorderSpacing.SetBothValuesTo(xValue); + mTempData.SetPropertyBit(eCSSProperty_border_spacing); return PR_TRUE; } } @@ -5649,8 +5648,9 @@ PRBool CSSParserImpl::ParsePlayDuring(nsresult& aErrorCode) } } if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_play_during_uri, playDuring); - AppendValue(eCSSProperty_play_during_flags, flags); + mTempData.mAural.mPlayDuring.mXValue = playDuring; + mTempData.mAural.mPlayDuring.mYValue = flags; + mTempData.SetPropertyBit(eCSSProperty_play_during); return PR_TRUE; } } @@ -5713,16 +5713,17 @@ PRBool CSSParserImpl::ParseSize(nsresult& aErrorCode) nsCSSValue height; if (ParseVariant(aErrorCode, height, VARIANT_LENGTH, nsnull)) { if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_size_width, width); - AppendValue(eCSSProperty_size_height, height); + mTempData.mPage.mSize.mXValue = width; + mTempData.mPage.mSize.mYValue = height; + mTempData.SetPropertyBit(eCSSProperty_size); return PR_TRUE; } return PR_FALSE; } } if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_size_width, width); - AppendValue(eCSSProperty_size_height, width); + mTempData.mPage.mSize.SetBothValuesTo(width); + mTempData.SetPropertyBit(eCSSProperty_size); return PR_TRUE; } } diff --git a/content/html/style/src/nsCSSStruct.cpp b/content/html/style/src/nsCSSStruct.cpp index a4cac3eaa957..c6d5b3f6a3b6 100644 --- a/content/html/style/src/nsCSSStruct.cpp +++ b/content/html/style/src/nsCSSStruct.cpp @@ -49,6 +49,8 @@ #include "nsStyleConsts.h" #include "nsCOMPtr.h" +#include "nsReadableUtils.h" +#include "nsPrintfCString.h" #define CSS_IF_DELETE(ptr) if (nsnull != ptr) { delete ptr; ptr = nsnull; } @@ -382,6 +384,25 @@ void nsCSSRect::List(FILE* out, PRInt32 aIndent, const nsCSSProperty aTRBL[]) co } #endif +// --- nsCSSValuePair ------------------- +#ifdef DEBUG +void nsCSSValuePair::AppendToString(nsAString& aString, + nsCSSProperty aPropName) const +{ + if (mXValue.GetUnit() != eCSSUnit_Null) { + AppendUTF8toUTF16(nsCSSProps::GetStringValue(aPropName), aString); + aString.Append(NS_LITERAL_STRING(": ")); + mXValue.AppendToString(aString); + NS_ASSERTION(mYValue.GetUnit() != eCSSUnit_Null, + nsPrintfCString("Parsed half of a %s?", + nsCSSProps::GetStringValue(aPropName).get()).get()); + aString.Append(PRUnichar(' ')); + mYValue.AppendToString(aString); + } +} +#endif + + // --- nsCSSValueListRect ----------------- MOZ_DECL_CTOR_COUNTER(nsCSSValueListRect) @@ -738,8 +759,7 @@ nsCSSTable::nsCSSTable(void) nsCSSTable::nsCSSTable(const nsCSSTable& aCopy) : mBorderCollapse(aCopy.mBorderCollapse), - mBorderSpacingX(aCopy.mBorderSpacingX), - mBorderSpacingY(aCopy.mBorderSpacingY), + mBorderSpacing(aCopy.mBorderSpacing), mCaptionSide(aCopy.mCaptionSide), mEmptyCells(aCopy.mEmptyCells), mLayout(aCopy.mLayout) @@ -760,8 +780,7 @@ void nsCSSTable::List(FILE* out, PRInt32 aIndent) const nsAutoString buffer; mBorderCollapse.AppendToString(buffer, eCSSProperty_border_collapse); - mBorderSpacingX.AppendToString(buffer, eCSSProperty_border_x_spacing); - mBorderSpacingY.AppendToString(buffer, eCSSProperty_border_y_spacing); + mBorderSpacing.AppendToString(buffer, eCSSProperty_border_spacing); mCaptionSide.AppendToString(buffer, eCSSProperty_caption_side); mEmptyCells.AppendToString(buffer, eCSSProperty_empty_cells); mLayout.AppendToString(buffer, eCSSProperty_table_layout); @@ -822,8 +841,7 @@ nsCSSPage::nsCSSPage(void) nsCSSPage::nsCSSPage(const nsCSSPage& aCopy) : mMarks(aCopy.mMarks), - mSizeWidth(aCopy.mSizeWidth), - mSizeHeight(aCopy.mSizeHeight) + mSize(aCopy.mSize) { MOZ_COUNT_CTOR(nsCSSPage); } @@ -841,8 +859,7 @@ void nsCSSPage::List(FILE* out, PRInt32 aIndent) const nsAutoString buffer; mMarks.AppendToString(buffer, eCSSProperty_marks); - mSizeWidth.AppendToString(buffer, eCSSProperty_size_width); - mSizeHeight.AppendToString(buffer, eCSSProperty_size_height); + mSize.AppendToString(buffer, eCSSProperty_size); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } @@ -1068,7 +1085,6 @@ nsCSSAural::nsCSSAural(const nsCSSAural& aCopy) mPitch(aCopy.mPitch), mPitchRange(aCopy.mPitchRange), mPlayDuring(aCopy.mPlayDuring), - mPlayDuringFlags(aCopy.mPlayDuringFlags), mRichness(aCopy.mRichness), mSpeak(aCopy.mSpeak), mSpeakHeader(aCopy.mSpeakHeader), @@ -1102,8 +1118,7 @@ void nsCSSAural::List(FILE* out, PRInt32 aIndent) const mPauseBefore.AppendToString(buffer, eCSSProperty_pause_before); mPitch.AppendToString(buffer, eCSSProperty_pitch); mPitchRange.AppendToString(buffer, eCSSProperty_pitch_range); - mPlayDuring.AppendToString(buffer, eCSSProperty_play_during_uri); - mPlayDuringFlags.AppendToString(buffer, eCSSProperty_play_during_flags); + mPlayDuring.AppendToString(buffer, eCSSProperty_play_during); mRichness.AppendToString(buffer, eCSSProperty_richness); mSpeak.AppendToString(buffer, eCSSProperty_speak); mSpeakHeader.AppendToString(buffer, eCSSProperty_speak_header); diff --git a/content/html/style/src/nsCSSStruct.h b/content/html/style/src/nsCSSStruct.h index ae641fcff599..69c1dee785a4 100644 --- a/content/html/style/src/nsCSSStruct.h +++ b/content/html/style/src/nsCSSStruct.h @@ -199,6 +199,47 @@ struct nsCSSRect { static const side_type sides[4]; }; +MOZ_DECL_CTOR_COUNTER(nsCSSValuePair) + +struct nsCSSValuePair { + nsCSSValuePair() + { + MOZ_COUNT_CTOR(nsCSSValuePair); + } + nsCSSValuePair(const nsCSSValuePair& aCopy) + : mXValue(aCopy.mXValue), + mYValue(aCopy.mYValue) + { + MOZ_COUNT_CTOR(nsCSSValuePair); + } + ~nsCSSValuePair() + { + MOZ_COUNT_DTOR(nsCSSValuePair); + } + + PRBool operator==(const nsCSSValuePair& aOther) const { + return mXValue == aOther.mXValue && + mYValue == aOther.mYValue; + } + + PRBool operator!=(const nsCSSValuePair& aOther) const { + return mXValue != aOther.mXValue || + mYValue != aOther.mYValue; + } + + void SetBothValuesTo(const nsCSSValue& aValue) { + mXValue = aValue; + mYValue = aValue; + } + +#ifdef DEBUG + void AppendToString(nsAString& aString, nsCSSProperty aPropName) const; +#endif + + nsCSSValue mXValue; + nsCSSValue mYValue; +}; + struct nsCSSValueListRect { nsCSSValueListRect(void); nsCSSValueListRect(const nsCSSValueListRect& aCopy); @@ -338,8 +379,7 @@ struct nsCSSTable : public nsCSSStruct { // NEW #endif nsCSSValue mBorderCollapse; - nsCSSValue mBorderSpacingX; - nsCSSValue mBorderSpacingY; + nsCSSValuePair mBorderSpacing; nsCSSValue mCaptionSide; nsCSSValue mEmptyCells; @@ -384,8 +424,7 @@ struct nsCSSPage : public nsCSSStruct { // NEW #endif nsCSSValue mMarks; - nsCSSValue mSizeWidth; - nsCSSValue mSizeHeight; + nsCSSValuePair mSize; }; struct nsRuleDataPage : public nsCSSPage { @@ -473,8 +512,7 @@ struct nsCSSAural : public nsCSSStruct { // NEW nsCSSValue mPauseBefore; nsCSSValue mPitch; nsCSSValue mPitchRange; - nsCSSValue mPlayDuring; - nsCSSValue mPlayDuringFlags; + nsCSSValuePair mPlayDuring; // mXValue is URI, mYValue are flags nsCSSValue mRichness; nsCSSValue mSpeak; nsCSSValue mSpeakHeader; diff --git a/content/html/style/src/nsComputedDOMStyle.cpp b/content/html/style/src/nsComputedDOMStyle.cpp index dbdd5b85c352..4be1af210cd0 100644 --- a/content/html/style/src/nsComputedDOMStyle.cpp +++ b/content/html/style/src/nsComputedDOMStyle.cpp @@ -972,7 +972,41 @@ nsresult nsComputedDOMStyle::GetBorderSpacing(nsIFrame *aFrame, nsIDOMCSSValue** aValue) { - return NS_ERROR_DOM_NOT_SUPPORTED_ERR; + nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE); + NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleTableBorder *border = nsnull; + GetStyleData(eStyleStruct_TableBorder, (const nsStyleStruct*&)border, aFrame); + if (border) { + nsROCSSPrimitiveValue* xSpacing = GetROCSSPrimitiveValue(); + if (!xSpacing) { + delete valueList; + return NS_ERROR_OUT_OF_MEMORY; + } + if (!valueList->AppendCSSValue(xSpacing)) { + delete valueList; + delete xSpacing; + return NS_ERROR_OUT_OF_MEMORY; + } + + nsROCSSPrimitiveValue* ySpacing = GetROCSSPrimitiveValue(); + if (!ySpacing) { + delete valueList; + return NS_ERROR_OUT_OF_MEMORY; + } + if (!valueList->AppendCSSValue(ySpacing)) { + delete valueList; + delete ySpacing; + return NS_ERROR_OUT_OF_MEMORY; + } + + // border-spacing will always be a coord + xSpacing->SetTwips(border->mBorderSpacingX.GetCoordValue()); + ySpacing->SetTwips(border->mBorderSpacingY.GetCoordValue()); + + } + + return CallQueryInterface(valueList, aValue); } nsresult @@ -3522,7 +3556,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength) COMPUTED_STYLE_MAP_ENTRY(border_right_color, BorderRightColor), COMPUTED_STYLE_MAP_ENTRY(border_right_style, BorderRightStyle), COMPUTED_STYLE_MAP_ENTRY(border_right_width, BorderRightWidth), - //// COMPUTED_STYLE_MAP_ENTRY(border_spacing, BorderSpacing), + COMPUTED_STYLE_MAP_ENTRY(border_spacing, BorderSpacing), //// COMPUTED_STYLE_MAP_ENTRY(border_style, BorderStyle), //// COMPUTED_STYLE_MAP_ENTRY(border_top, BorderTop), COMPUTED_STYLE_MAP_ENTRY(border_top_color, BorderTopColor), diff --git a/content/shared/public/nsCSSPropList.h b/content/shared/public/nsCSSPropList.h index bdab54964bd0..383b027862a7 100644 --- a/content/shared/public/nsCSSPropList.h +++ b/content/shared/public/nsCSSPropList.h @@ -312,7 +312,7 @@ CSS_PROP_BORDER(border-right-color, border_right_color, BorderRightColor, Margin CSS_PROP_BORDER(-moz-border-right-colors, border_right_colors, MozBorderRightColors, Margin, mBorderColors.mRight, eCSSType_ValueList, PR_FALSE, nsnull) CSS_PROP_BORDER(border-right-style, border_right_style, BorderRightStyle, Margin, mBorderStyle.mRight, eCSSType_Value, PR_FALSE, kBorderStyleKTable) // on/off will need reflow CSS_PROP_BORDER(border-right-width, border_right_width, BorderRightWidth, Margin, mBorderWidth.mRight, eCSSType_Value, PR_FALSE, kBorderWidthKTable) -CSS_PROP_SHORTHAND(border-spacing, border_spacing, BorderSpacing) +CSS_PROP_TABLEBORDER(border-spacing, border_spacing, BorderSpacing, Table, mBorderSpacing, eCSSType_ValuePair, PR_FALSE, nsnull) // XXX bug 3935 CSS_PROP_SHORTHAND(border-style, border_style, BorderStyle) // on/off will need reflow CSS_PROP_SHORTHAND(border-top, border_top, BorderTop) CSS_PROP_BORDER(border-top-color, border_top_color, BorderTopColor, Margin, mBorderColor.mTop, eCSSType_Value, PR_FALSE, kBorderColorKTable) @@ -320,10 +320,6 @@ CSS_PROP_BORDER(-moz-border-top-colors, border_top_colors, MozBorderTopColors, M CSS_PROP_BORDER(border-top-style, border_top_style, BorderTopStyle, Margin, mBorderStyle.mTop, eCSSType_Value, PR_FALSE, kBorderStyleKTable) // on/off will need reflow CSS_PROP_BORDER(border-top-width, border_top_width, BorderTopWidth, Margin, mBorderWidth.mTop, eCSSType_Value, PR_FALSE, kBorderWidthKTable) CSS_PROP_SHORTHAND(border-width, border_width, BorderWidth) -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_TABLEBORDER(-x-border-x-spacing, border_x_spacing, BorderXSpacing, Table, mBorderSpacingX, eCSSType_Value, PR_FALSE, nsnull) // XXX bug 3935 -CSS_PROP_TABLEBORDER(-x-border-y-spacing, border_y_spacing, BorderYSpacing, Table, mBorderSpacingY, eCSSType_Value, PR_FALSE, nsnull) // XXX bug 3935 -#endif /* !defined (CSS_PROP_LIST_EXCLUDE_INTERNAL) */ CSS_PROP_POSITION(bottom, bottom, Bottom, Position, mOffset.mBottom, eCSSType_Value, PR_TRUE, nsnull) CSS_PROP_POSITION(-moz-box-sizing, box_sizing, MozBoxSizing, Position, mBoxSizing, eCSSType_Value, PR_FALSE, kBoxSizingKTable) // XXX bug 3935 CSS_PROP_TABLEBORDER(caption-side, caption_side, CaptionSide, Table, mCaptionSide, eCSSType_Value, PR_FALSE, kCaptionSideKTable) @@ -441,20 +437,12 @@ CSS_PROP_BACKENDONLY(pause-after, pause_after, PauseAfter, Aural, mPauseAfter, e CSS_PROP_BACKENDONLY(pause-before, pause_before, PauseBefore, Aural, mPauseBefore, eCSSType_Value, PR_FALSE, nsnull) CSS_PROP_BACKENDONLY(pitch, pitch, Pitch, Aural, mPitch, eCSSType_Value, PR_FALSE, kPitchKTable) CSS_PROP_BACKENDONLY(pitch-range, pitch_range, PitchRange, Aural, mPitchRange, eCSSType_Value, PR_FALSE, nsnull) -CSS_PROP_SHORTHAND(play-during, play_during, PlayDuring) -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_BACKENDONLY(-x-play-during-flags, play_during_flags, PlayDuringFlags, Aural, mPlayDuringFlags, eCSSType_Value, PR_FALSE, kPlayDuringKTable) // XXX why is this here? -CSS_PROP_BACKENDONLY(-x-play-during-uri, play_during_uri, PlayDuringURI, Aural, mPlayDuring, eCSSType_Value, PR_FALSE, nsnull) // XXX why is this here? -#endif /* !defined (CSS_PROP_LIST_EXCLUDE_INTERNAL) */ +CSS_PROP_BACKENDONLY(play-during, play_during, PlayDuring, Aural, mPlayDuring, eCSSType_ValuePair, PR_FALSE, kPlayDuringKTable) CSS_PROP_DISPLAY(position, position, Position, Display, mPosition, eCSSType_Value, PR_FALSE, kPositionKTable) CSS_PROP_QUOTES(quotes, quotes, Quotes, Content, mQuotes, eCSSType_Quotes, PR_FALSE, nsnull) CSS_PROP_BACKENDONLY(richness, richness, Richness, Aural, mRichness, eCSSType_Value, PR_FALSE, nsnull) CSS_PROP_POSITION(right, right, Right, Position, mOffset.mRight, eCSSType_Value, PR_TRUE, nsnull) -CSS_PROP_SHORTHAND(size, size, Size) -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_BACKENDONLY(-x-size-height, size_height, SizeHeight, Page, mSizeHeight, eCSSType_Value, PR_FALSE, kPageSizeKTable) // XXX bug 3935 -CSS_PROP_BACKENDONLY(-x-size-width, size_width, SizeWidth, Page, mSizeWidth, eCSSType_Value, PR_FALSE, kPageSizeKTable) // XXX bug 3935 -#endif /* !defined (CSS_PROP_LIST_EXCLUDE_INTERNAL) */ +CSS_PROP_BACKENDONLY(size, size, Size, Page, mSize, eCSSType_ValuePair, PR_FALSE, kPageSizeKTable) CSS_PROP_BACKENDONLY(speak, speak, Speak, Aural, mSpeak, eCSSType_Value, PR_FALSE, kSpeakKTable) CSS_PROP_BACKENDONLY(speak-header, speak_header, SpeakHeader, Aural, mSpeakHeader, eCSSType_Value, PR_FALSE, kSpeakHeaderKTable) CSS_PROP_BACKENDONLY(speak-numeral, speak_numeral, SpeakNumeral, Aural, mSpeakNumeral, eCSSType_Value, PR_FALSE, kSpeakNumeralKTable) diff --git a/content/shared/public/nsCSSProperty.h b/content/shared/public/nsCSSProperty.h index 2f807a8339c5..128a08258611 100644 --- a/content/shared/public/nsCSSProperty.h +++ b/content/shared/public/nsCSSProperty.h @@ -67,6 +67,7 @@ enum nsCSSProperty { enum nsCSSType { eCSSType_Value, eCSSType_Rect, + eCSSType_ValuePair, eCSSType_ValueList, eCSSType_CounterData, eCSSType_Quotes, diff --git a/content/shared/src/nsCSSProps.cpp b/content/shared/src/nsCSSProps.cpp index bc1449bcb383..18f499fc901b 100644 --- a/content/shared/src/nsCSSProps.cpp +++ b/content/shared/src/nsCSSProps.cpp @@ -1215,12 +1215,6 @@ static const nsCSSProperty gBorderRightSubpropTable[] = { eCSSProperty_UNKNOWN }; -static const nsCSSProperty gBorderSpacingSubpropTable[] = { - eCSSProperty_border_x_spacing, - eCSSProperty_border_y_spacing, - eCSSProperty_UNKNOWN -}; - static const nsCSSProperty gBorderStyleSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_border_top_style, @@ -1385,18 +1379,6 @@ static const nsCSSProperty gPauseSubpropTable[] = { eCSSProperty_UNKNOWN }; -static const nsCSSProperty gPlayDuringSubpropTable[] = { - eCSSProperty_play_during_uri, - eCSSProperty_play_during_flags, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gSizeSubpropTable[] = { - eCSSProperty_size_width, - eCSSProperty_size_height, - eCSSProperty_UNKNOWN -}; - const nsCSSProperty *const nsCSSProps::kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP_SHORTHAND(name_, id_, method_) g##method_##SubpropTable, diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index c54e613855cb..d33701220938 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * @@ -66,6 +67,11 @@ struct CDBRectStorage { }; +struct CDBValuePairStorage { + nsCSSProperty property; + nsCSSValuePair value; +}; + struct CDBPointerStorage { nsCSSProperty property; void *value; @@ -74,6 +80,7 @@ struct CDBPointerStorage { enum { CDBValueStorage_advance = sizeof(CDBValueStorage), CDBRectStorage_advance = sizeof(CDBRectStorage), + CDBValuePairStorage_advance = sizeof(CDBValuePairStorage), // round up using the closest estimate we can get of the alignment // requirements of nsCSSValue: CDBPointerStorage_advance = PR_ROUNDUP(sizeof(CDBPointerStorage), @@ -112,6 +119,14 @@ inline const nsCSSRect* RectAtCursor(const char *aCursor) { return & NS_REINTERPRET_CAST(const CDBRectStorage*, aCursor)->value; } +inline nsCSSValuePair* ValuePairAtCursor(char *aCursor) { + return & NS_REINTERPRET_CAST(CDBValuePairStorage*, aCursor)->value; +} + +inline const nsCSSValuePair* ValuePairAtCursor(const char *aCursor) { + return & NS_REINTERPRET_CAST(const CDBValuePairStorage*, aCursor)->value; +} + inline void*& PointerAtCursor(char *aCursor) { return NS_REINTERPRET_CAST(CDBPointerStorage*, aCursor)->value; } @@ -215,6 +230,18 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + nsCSSValuePair* target = NS_STATIC_CAST(nsCSSValuePair*, prop); + if (target->mXValue.GetUnit() == eCSSUnit_Null) + target->mXValue = val->mXValue; + if (target->mYValue.GetUnit() == eCSSUnit_Null) + target->mYValue = val->mYValue; + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: if (iProp == eCSSProperty_content) { for (nsCSSValueList* l = ValueListAtCursor(cursor); @@ -246,6 +273,10 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -285,6 +316,9 @@ nsCSSCompressedDataBlock::StorageFor(nsCSSProperty aProperty) const case eCSSType_Rect: { return RectAtCursor(cursor); } + case eCSSType_ValuePair: { + return ValuePairAtCursor(cursor); + } case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -302,6 +336,10 @@ nsCSSCompressedDataBlock::StorageFor(nsCSSProperty aProperty) const cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -352,6 +390,16 @@ nsCSSCompressedDataBlock::Clone() const result_cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + nsCSSValuePair* result_val = ValuePairAtCursor(result_cursor); + new (result_val) nsCSSValuePair(*val); + cursor += CDBValuePairStorage_advance; + result_cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -421,6 +469,14 @@ nsCSSCompressedDataBlock::Destroy() cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + val->~nsCSSValuePair(); + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: { nsCSSValueList* val = ValueListAtCursor(cursor); NS_ASSERTION(val, "oops"); @@ -532,6 +588,14 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock, cursor += CDBRectStorage_advance; } break; + case eCSSType_ValuePair: { + const nsCSSValuePair* val = ValuePairAtCursor(cursor); + NS_ASSERTION(val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null, "oops"); + memcpy(prop, val, sizeof(nsCSSValuePair)); + cursor += CDBValuePairStorage_advance; + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -594,6 +658,14 @@ nsCSSExpandedDataBlock::ComputeSize() } } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + if (val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null) { + increment = CDBValuePairStorage_advance; + } + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -692,6 +764,20 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, } } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + if (val->mXValue.GetUnit() != eCSSUnit_Null || + val->mYValue.GetUnit() != eCSSUnit_Null) { + CDBValuePairStorage *storage = + NS_REINTERPRET_CAST(CDBValuePairStorage*, cursor); + storage->property = iProp; + memcpy(&storage->value, val, sizeof(nsCSSValuePair)); + new (val) nsCSSValuePair(); + cursor += CDBValuePairStorage_advance; + present = PR_TRUE; + } + } break; + case eCSSType_ValueList: case eCSSType_CounterData: case eCSSType_Quotes: @@ -769,6 +855,12 @@ nsCSSExpandedDataBlock::ClearProperty(nsCSSProperty aPropID) val->Reset(); } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + val->mXValue.Reset(); + val->mYValue.Reset(); + } break; + case eCSSType_ValueList: { nsCSSValueList*& val = *NS_STATIC_CAST(nsCSSValueList**, prop); if (val) { @@ -837,6 +929,14 @@ nsCSSExpandedDataBlock::DoAssertInitialState() "not initial state"); } break; + case eCSSType_ValuePair: { + nsCSSValuePair* val = NS_STATIC_CAST(nsCSSValuePair*, prop); + NS_ASSERTION(val->mXValue.GetUnit() == eCSSUnit_Null, + "not initial state"); + NS_ASSERTION(val->mYValue.GetUnit() == eCSSUnit_Null, + "not initial state"); + } break; + case eCSSType_ValueList: { nsCSSValueList* val = *NS_STATIC_CAST(nsCSSValueList**, prop); NS_ASSERTION(val == nsnull, "not initial state"); diff --git a/layout/style/nsCSSDeclaration.cpp b/layout/style/nsCSSDeclaration.cpp index 46a5b2eec2b3..671b7c3c3489 100644 --- a/layout/style/nsCSSDeclaration.cpp +++ b/layout/style/nsCSSDeclaration.cpp @@ -40,6 +40,7 @@ #include "nsString.h" #include "nsIAtom.h" #include "nsUnicharUtils.h" +#include "nsReadableUtils.h" #include "nsCRT.h" #include "nsCSSProps.h" #include "nsUnitConversion.h" @@ -214,6 +215,15 @@ PRBool nsCSSDeclaration::AppendValueToString(nsCSSProperty aProperty, nsAString& aResult.Append(PRUnichar(')')); } } break; + case eCSSType_ValuePair: { + const nsCSSValuePair *pair = NS_STATIC_CAST(const nsCSSValuePair*, storage); + AppendCSSValueToString(aProperty, pair->mXValue, aResult); + if (pair->mYValue != pair->mXValue) { + // Only output a Y value if it's different from the X value + aResult.Append(PRUnichar(' ')); + AppendCSSValueToString(aProperty, pair->mYValue, aResult); + } + } break; case eCSSType_ValueList: { const nsCSSValueList* val = *NS_STATIC_CAST(nsCSSValueList*const*, storage); @@ -364,18 +374,6 @@ PRBool nsCSSDeclaration::AppendCSSValueToString(nsCSSProperty aProperty, const n AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, NS_STYLE_AZIMUTH_BEHIND), aResult); } } - else if (eCSSProperty_play_during_flags == aProperty) { - PRInt32 intValue = aValue.GetIntValue(); - if ((NS_STYLE_PLAY_DURING_MIX & intValue) != 0) { - AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, NS_STYLE_PLAY_DURING_MIX), aResult); - } - if ((NS_STYLE_PLAY_DURING_REPEAT & intValue) != 0) { - if (NS_STYLE_PLAY_DURING_REPEAT != intValue) { - aResult.Append(PRUnichar(' ')); - } - AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, NS_STYLE_PLAY_DURING_REPEAT), aResult); - } - } else if (eCSSProperty_marks == aProperty) { PRInt32 intValue = aValue.GetIntValue(); if ((NS_STYLE_PAGE_MARKS_CROP & intValue) != 0) { @@ -493,7 +491,9 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, aValue.Truncate(0); // simple properties are easy. - if (!nsCSSProps::IsShorthand(aProperty)) { + if (!nsCSSProps::IsShorthand(aProperty) && + // play-during is not a real shorthand, but is special... + aProperty != eCSSProperty_play_during) { AppendValueToString(aProperty, aValue); return NS_OK; } @@ -584,16 +584,6 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, } break; } - case eCSSProperty_border_spacing: - if (AppendValueToString(eCSSProperty_border_x_spacing, aValue)) { - aValue.Append(PRUnichar(' ')); -#ifdef DEBUG - PRBool check = -#endif - AppendValueToString(eCSSProperty_border_y_spacing, aValue); - NS_ASSERTION(check, "we parsed half of border-spacing"); - } - break; case eCSSProperty_cue: { if (AppendValueToString(eCSSProperty_cue_after, aValue)) { aValue.Append(PRUnichar(' ')); @@ -646,14 +636,6 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, } break; } - case eCSSProperty_size: { - if (AppendValueToString(eCSSProperty_size_width, aValue)) { - aValue.Append(PRUnichar(' ')); - if (!AppendValueToString(eCSSProperty_size_height, aValue)) - aValue.Truncate(); - } - break; - } case eCSSProperty_background_position: { if (AppendValueToString(eCSSProperty_background_x_position, aValue)) { aValue.Append(PRUnichar(' ')); @@ -666,11 +648,32 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, break; } case eCSSProperty_play_during: { - if (AppendValueToString(eCSSProperty_play_during_uri, aValue)) { - nsAutoString tmp; - if (AppendValueToString(eCSSProperty_play_during_flags, tmp)) { - aValue.Append(PRUnichar(' ')); - aValue.Append(tmp); + nsCSSCompressedDataBlock *data = + GetValueIsImportant(eCSSProperty_play_during) ? mImportantData : mData; + const void *storage = data->StorageFor(eCSSProperty_play_during); + if (!storage) { + break; + } + NS_ASSERTION(nsCSSProps::kTypeTable[eCSSProperty_play_during] == + eCSSType_ValuePair, + "Someone changed the storage type of play-during!"); + const nsCSSValuePair *pair = NS_STATIC_CAST(const nsCSSValuePair*, storage); + AppendCSSValueToString(aProperty, pair->mXValue, aValue); + if (pair->mYValue != eCSSUnit_Null) { + aValue.Append(PRUnichar(' ')); + PRInt32 intValue = pair->mYValue.GetIntValue(); + if ((NS_STYLE_PLAY_DURING_MIX & intValue) != 0) { + AppendUTF8toUTF16(nsCSSProps::LookupPropertyValue(aProperty, + NS_STYLE_PLAY_DURING_MIX), + aValue); + } + if ((NS_STYLE_PLAY_DURING_REPEAT & intValue) != 0) { + if (NS_STYLE_PLAY_DURING_REPEAT != intValue) { + aValue.Append(PRUnichar(' ')); + } + AppendUTF8toUTF16(nsCSSProps::LookupPropertyValue(aProperty, + NS_STYLE_PLAY_DURING_REPEAT), + aValue); } } break; diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 4f39655dab6d..fd4e766ee153 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -3223,6 +3223,16 @@ CSSParserImpl::DoTransferTempData(nsCSSDeclaration* aDeclaration, new (source) nsCSSRect(); } break; + case eCSSType_ValuePair: { + nsCSSValuePair *source = NS_STATIC_CAST(nsCSSValuePair*, v_source); + nsCSSValuePair *dest = NS_STATIC_CAST(nsCSSValuePair*, v_dest); + if (*source != *dest) + *aChanged = PR_TRUE; + dest->~nsCSSValuePair(); + memcpy(dest, source, sizeof(nsCSSValuePair)); + new (source) nsCSSValuePair(); + } break; + case eCSSType_ValueList: { nsCSSValueList **source = NS_STATIC_CAST(nsCSSValueList**, v_source); nsCSSValueList **dest = NS_STATIC_CAST(nsCSSValueList**, v_dest); @@ -4060,12 +4070,6 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, // by compound property parsing routines (e.g. "background-position"). case eCSSProperty_background_x_position: case eCSSProperty_background_y_position: - case eCSSProperty_border_x_spacing: - case eCSSProperty_border_y_spacing: - case eCSSProperty_play_during_flags: - case eCSSProperty_play_during_uri: - case eCSSProperty_size_height: - case eCSSProperty_size_width: case eCSSProperty_margin_end_value: case eCSSProperty_margin_left_value: case eCSSProperty_margin_right_value: @@ -4179,12 +4183,6 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, NS_ERROR("not a single value property"); return PR_FALSE; - case eCSSProperty_border_x_spacing: - case eCSSProperty_border_y_spacing: - case eCSSProperty_play_during_flags: - case eCSSProperty_play_during_uri: - case eCSSProperty_size_height: - case eCSSProperty_size_width: case eCSSProperty_margin_left_ltr_source: case eCSSProperty_margin_left_rtl_source: case eCSSProperty_margin_right_ltr_source: @@ -4874,8 +4872,9 @@ PRBool CSSParserImpl::ParseBorderSpacing(nsresult& aErrorCode) if (ParsePositiveVariant(aErrorCode, yValue, VARIANT_LENGTH, nsnull)) { // We have two numbers if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_border_x_spacing, xValue); - AppendValue(eCSSProperty_border_y_spacing, yValue); + mTempData.mTable.mBorderSpacing.mXValue = xValue; + mTempData.mTable.mBorderSpacing.mYValue = yValue; + mTempData.SetPropertyBit(eCSSProperty_border_spacing); return PR_TRUE; } return PR_FALSE; @@ -4885,8 +4884,8 @@ PRBool CSSParserImpl::ParseBorderSpacing(nsresult& aErrorCode) // We have one length which is the horizontal spacing. Create a value for // the vertical spacing which is equal if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_border_x_spacing, xValue); - AppendValue(eCSSProperty_border_y_spacing, xValue); + mTempData.mTable.mBorderSpacing.SetBothValuesTo(xValue); + mTempData.SetPropertyBit(eCSSProperty_border_spacing); return PR_TRUE; } } @@ -5649,8 +5648,9 @@ PRBool CSSParserImpl::ParsePlayDuring(nsresult& aErrorCode) } } if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_play_during_uri, playDuring); - AppendValue(eCSSProperty_play_during_flags, flags); + mTempData.mAural.mPlayDuring.mXValue = playDuring; + mTempData.mAural.mPlayDuring.mYValue = flags; + mTempData.SetPropertyBit(eCSSProperty_play_during); return PR_TRUE; } } @@ -5713,16 +5713,17 @@ PRBool CSSParserImpl::ParseSize(nsresult& aErrorCode) nsCSSValue height; if (ParseVariant(aErrorCode, height, VARIANT_LENGTH, nsnull)) { if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_size_width, width); - AppendValue(eCSSProperty_size_height, height); + mTempData.mPage.mSize.mXValue = width; + mTempData.mPage.mSize.mYValue = height; + mTempData.SetPropertyBit(eCSSProperty_size); return PR_TRUE; } return PR_FALSE; } } if (ExpectEndProperty(aErrorCode, PR_TRUE)) { - AppendValue(eCSSProperty_size_width, width); - AppendValue(eCSSProperty_size_height, width); + mTempData.mPage.mSize.SetBothValuesTo(width); + mTempData.SetPropertyBit(eCSSProperty_size); return PR_TRUE; } } diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index bdab54964bd0..383b027862a7 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -312,7 +312,7 @@ CSS_PROP_BORDER(border-right-color, border_right_color, BorderRightColor, Margin CSS_PROP_BORDER(-moz-border-right-colors, border_right_colors, MozBorderRightColors, Margin, mBorderColors.mRight, eCSSType_ValueList, PR_FALSE, nsnull) CSS_PROP_BORDER(border-right-style, border_right_style, BorderRightStyle, Margin, mBorderStyle.mRight, eCSSType_Value, PR_FALSE, kBorderStyleKTable) // on/off will need reflow CSS_PROP_BORDER(border-right-width, border_right_width, BorderRightWidth, Margin, mBorderWidth.mRight, eCSSType_Value, PR_FALSE, kBorderWidthKTable) -CSS_PROP_SHORTHAND(border-spacing, border_spacing, BorderSpacing) +CSS_PROP_TABLEBORDER(border-spacing, border_spacing, BorderSpacing, Table, mBorderSpacing, eCSSType_ValuePair, PR_FALSE, nsnull) // XXX bug 3935 CSS_PROP_SHORTHAND(border-style, border_style, BorderStyle) // on/off will need reflow CSS_PROP_SHORTHAND(border-top, border_top, BorderTop) CSS_PROP_BORDER(border-top-color, border_top_color, BorderTopColor, Margin, mBorderColor.mTop, eCSSType_Value, PR_FALSE, kBorderColorKTable) @@ -320,10 +320,6 @@ CSS_PROP_BORDER(-moz-border-top-colors, border_top_colors, MozBorderTopColors, M CSS_PROP_BORDER(border-top-style, border_top_style, BorderTopStyle, Margin, mBorderStyle.mTop, eCSSType_Value, PR_FALSE, kBorderStyleKTable) // on/off will need reflow CSS_PROP_BORDER(border-top-width, border_top_width, BorderTopWidth, Margin, mBorderWidth.mTop, eCSSType_Value, PR_FALSE, kBorderWidthKTable) CSS_PROP_SHORTHAND(border-width, border_width, BorderWidth) -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_TABLEBORDER(-x-border-x-spacing, border_x_spacing, BorderXSpacing, Table, mBorderSpacingX, eCSSType_Value, PR_FALSE, nsnull) // XXX bug 3935 -CSS_PROP_TABLEBORDER(-x-border-y-spacing, border_y_spacing, BorderYSpacing, Table, mBorderSpacingY, eCSSType_Value, PR_FALSE, nsnull) // XXX bug 3935 -#endif /* !defined (CSS_PROP_LIST_EXCLUDE_INTERNAL) */ CSS_PROP_POSITION(bottom, bottom, Bottom, Position, mOffset.mBottom, eCSSType_Value, PR_TRUE, nsnull) CSS_PROP_POSITION(-moz-box-sizing, box_sizing, MozBoxSizing, Position, mBoxSizing, eCSSType_Value, PR_FALSE, kBoxSizingKTable) // XXX bug 3935 CSS_PROP_TABLEBORDER(caption-side, caption_side, CaptionSide, Table, mCaptionSide, eCSSType_Value, PR_FALSE, kCaptionSideKTable) @@ -441,20 +437,12 @@ CSS_PROP_BACKENDONLY(pause-after, pause_after, PauseAfter, Aural, mPauseAfter, e CSS_PROP_BACKENDONLY(pause-before, pause_before, PauseBefore, Aural, mPauseBefore, eCSSType_Value, PR_FALSE, nsnull) CSS_PROP_BACKENDONLY(pitch, pitch, Pitch, Aural, mPitch, eCSSType_Value, PR_FALSE, kPitchKTable) CSS_PROP_BACKENDONLY(pitch-range, pitch_range, PitchRange, Aural, mPitchRange, eCSSType_Value, PR_FALSE, nsnull) -CSS_PROP_SHORTHAND(play-during, play_during, PlayDuring) -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_BACKENDONLY(-x-play-during-flags, play_during_flags, PlayDuringFlags, Aural, mPlayDuringFlags, eCSSType_Value, PR_FALSE, kPlayDuringKTable) // XXX why is this here? -CSS_PROP_BACKENDONLY(-x-play-during-uri, play_during_uri, PlayDuringURI, Aural, mPlayDuring, eCSSType_Value, PR_FALSE, nsnull) // XXX why is this here? -#endif /* !defined (CSS_PROP_LIST_EXCLUDE_INTERNAL) */ +CSS_PROP_BACKENDONLY(play-during, play_during, PlayDuring, Aural, mPlayDuring, eCSSType_ValuePair, PR_FALSE, kPlayDuringKTable) CSS_PROP_DISPLAY(position, position, Position, Display, mPosition, eCSSType_Value, PR_FALSE, kPositionKTable) CSS_PROP_QUOTES(quotes, quotes, Quotes, Content, mQuotes, eCSSType_Quotes, PR_FALSE, nsnull) CSS_PROP_BACKENDONLY(richness, richness, Richness, Aural, mRichness, eCSSType_Value, PR_FALSE, nsnull) CSS_PROP_POSITION(right, right, Right, Position, mOffset.mRight, eCSSType_Value, PR_TRUE, nsnull) -CSS_PROP_SHORTHAND(size, size, Size) -#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL -CSS_PROP_BACKENDONLY(-x-size-height, size_height, SizeHeight, Page, mSizeHeight, eCSSType_Value, PR_FALSE, kPageSizeKTable) // XXX bug 3935 -CSS_PROP_BACKENDONLY(-x-size-width, size_width, SizeWidth, Page, mSizeWidth, eCSSType_Value, PR_FALSE, kPageSizeKTable) // XXX bug 3935 -#endif /* !defined (CSS_PROP_LIST_EXCLUDE_INTERNAL) */ +CSS_PROP_BACKENDONLY(size, size, Size, Page, mSize, eCSSType_ValuePair, PR_FALSE, kPageSizeKTable) CSS_PROP_BACKENDONLY(speak, speak, Speak, Aural, mSpeak, eCSSType_Value, PR_FALSE, kSpeakKTable) CSS_PROP_BACKENDONLY(speak-header, speak_header, SpeakHeader, Aural, mSpeakHeader, eCSSType_Value, PR_FALSE, kSpeakHeaderKTable) CSS_PROP_BACKENDONLY(speak-numeral, speak_numeral, SpeakNumeral, Aural, mSpeakNumeral, eCSSType_Value, PR_FALSE, kSpeakNumeralKTable) diff --git a/layout/style/nsCSSProperty.h b/layout/style/nsCSSProperty.h index 2f807a8339c5..128a08258611 100644 --- a/layout/style/nsCSSProperty.h +++ b/layout/style/nsCSSProperty.h @@ -67,6 +67,7 @@ enum nsCSSProperty { enum nsCSSType { eCSSType_Value, eCSSType_Rect, + eCSSType_ValuePair, eCSSType_ValueList, eCSSType_CounterData, eCSSType_Quotes, diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index bc1449bcb383..18f499fc901b 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -1215,12 +1215,6 @@ static const nsCSSProperty gBorderRightSubpropTable[] = { eCSSProperty_UNKNOWN }; -static const nsCSSProperty gBorderSpacingSubpropTable[] = { - eCSSProperty_border_x_spacing, - eCSSProperty_border_y_spacing, - eCSSProperty_UNKNOWN -}; - static const nsCSSProperty gBorderStyleSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_border_top_style, @@ -1385,18 +1379,6 @@ static const nsCSSProperty gPauseSubpropTable[] = { eCSSProperty_UNKNOWN }; -static const nsCSSProperty gPlayDuringSubpropTable[] = { - eCSSProperty_play_during_uri, - eCSSProperty_play_during_flags, - eCSSProperty_UNKNOWN -}; - -static const nsCSSProperty gSizeSubpropTable[] = { - eCSSProperty_size_width, - eCSSProperty_size_height, - eCSSProperty_UNKNOWN -}; - const nsCSSProperty *const nsCSSProps::kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands] = { #define CSS_PROP_SHORTHAND(name_, id_, method_) g##method_##SubpropTable, diff --git a/layout/style/nsCSSStruct.cpp b/layout/style/nsCSSStruct.cpp index a4cac3eaa957..c6d5b3f6a3b6 100644 --- a/layout/style/nsCSSStruct.cpp +++ b/layout/style/nsCSSStruct.cpp @@ -49,6 +49,8 @@ #include "nsStyleConsts.h" #include "nsCOMPtr.h" +#include "nsReadableUtils.h" +#include "nsPrintfCString.h" #define CSS_IF_DELETE(ptr) if (nsnull != ptr) { delete ptr; ptr = nsnull; } @@ -382,6 +384,25 @@ void nsCSSRect::List(FILE* out, PRInt32 aIndent, const nsCSSProperty aTRBL[]) co } #endif +// --- nsCSSValuePair ------------------- +#ifdef DEBUG +void nsCSSValuePair::AppendToString(nsAString& aString, + nsCSSProperty aPropName) const +{ + if (mXValue.GetUnit() != eCSSUnit_Null) { + AppendUTF8toUTF16(nsCSSProps::GetStringValue(aPropName), aString); + aString.Append(NS_LITERAL_STRING(": ")); + mXValue.AppendToString(aString); + NS_ASSERTION(mYValue.GetUnit() != eCSSUnit_Null, + nsPrintfCString("Parsed half of a %s?", + nsCSSProps::GetStringValue(aPropName).get()).get()); + aString.Append(PRUnichar(' ')); + mYValue.AppendToString(aString); + } +} +#endif + + // --- nsCSSValueListRect ----------------- MOZ_DECL_CTOR_COUNTER(nsCSSValueListRect) @@ -738,8 +759,7 @@ nsCSSTable::nsCSSTable(void) nsCSSTable::nsCSSTable(const nsCSSTable& aCopy) : mBorderCollapse(aCopy.mBorderCollapse), - mBorderSpacingX(aCopy.mBorderSpacingX), - mBorderSpacingY(aCopy.mBorderSpacingY), + mBorderSpacing(aCopy.mBorderSpacing), mCaptionSide(aCopy.mCaptionSide), mEmptyCells(aCopy.mEmptyCells), mLayout(aCopy.mLayout) @@ -760,8 +780,7 @@ void nsCSSTable::List(FILE* out, PRInt32 aIndent) const nsAutoString buffer; mBorderCollapse.AppendToString(buffer, eCSSProperty_border_collapse); - mBorderSpacingX.AppendToString(buffer, eCSSProperty_border_x_spacing); - mBorderSpacingY.AppendToString(buffer, eCSSProperty_border_y_spacing); + mBorderSpacing.AppendToString(buffer, eCSSProperty_border_spacing); mCaptionSide.AppendToString(buffer, eCSSProperty_caption_side); mEmptyCells.AppendToString(buffer, eCSSProperty_empty_cells); mLayout.AppendToString(buffer, eCSSProperty_table_layout); @@ -822,8 +841,7 @@ nsCSSPage::nsCSSPage(void) nsCSSPage::nsCSSPage(const nsCSSPage& aCopy) : mMarks(aCopy.mMarks), - mSizeWidth(aCopy.mSizeWidth), - mSizeHeight(aCopy.mSizeHeight) + mSize(aCopy.mSize) { MOZ_COUNT_CTOR(nsCSSPage); } @@ -841,8 +859,7 @@ void nsCSSPage::List(FILE* out, PRInt32 aIndent) const nsAutoString buffer; mMarks.AppendToString(buffer, eCSSProperty_marks); - mSizeWidth.AppendToString(buffer, eCSSProperty_size_width); - mSizeHeight.AppendToString(buffer, eCSSProperty_size_height); + mSize.AppendToString(buffer, eCSSProperty_size); fputs(NS_LossyConvertUCS2toASCII(buffer).get(), out); } @@ -1068,7 +1085,6 @@ nsCSSAural::nsCSSAural(const nsCSSAural& aCopy) mPitch(aCopy.mPitch), mPitchRange(aCopy.mPitchRange), mPlayDuring(aCopy.mPlayDuring), - mPlayDuringFlags(aCopy.mPlayDuringFlags), mRichness(aCopy.mRichness), mSpeak(aCopy.mSpeak), mSpeakHeader(aCopy.mSpeakHeader), @@ -1102,8 +1118,7 @@ void nsCSSAural::List(FILE* out, PRInt32 aIndent) const mPauseBefore.AppendToString(buffer, eCSSProperty_pause_before); mPitch.AppendToString(buffer, eCSSProperty_pitch); mPitchRange.AppendToString(buffer, eCSSProperty_pitch_range); - mPlayDuring.AppendToString(buffer, eCSSProperty_play_during_uri); - mPlayDuringFlags.AppendToString(buffer, eCSSProperty_play_during_flags); + mPlayDuring.AppendToString(buffer, eCSSProperty_play_during); mRichness.AppendToString(buffer, eCSSProperty_richness); mSpeak.AppendToString(buffer, eCSSProperty_speak); mSpeakHeader.AppendToString(buffer, eCSSProperty_speak_header); diff --git a/layout/style/nsCSSStruct.h b/layout/style/nsCSSStruct.h index ae641fcff599..69c1dee785a4 100644 --- a/layout/style/nsCSSStruct.h +++ b/layout/style/nsCSSStruct.h @@ -199,6 +199,47 @@ struct nsCSSRect { static const side_type sides[4]; }; +MOZ_DECL_CTOR_COUNTER(nsCSSValuePair) + +struct nsCSSValuePair { + nsCSSValuePair() + { + MOZ_COUNT_CTOR(nsCSSValuePair); + } + nsCSSValuePair(const nsCSSValuePair& aCopy) + : mXValue(aCopy.mXValue), + mYValue(aCopy.mYValue) + { + MOZ_COUNT_CTOR(nsCSSValuePair); + } + ~nsCSSValuePair() + { + MOZ_COUNT_DTOR(nsCSSValuePair); + } + + PRBool operator==(const nsCSSValuePair& aOther) const { + return mXValue == aOther.mXValue && + mYValue == aOther.mYValue; + } + + PRBool operator!=(const nsCSSValuePair& aOther) const { + return mXValue != aOther.mXValue || + mYValue != aOther.mYValue; + } + + void SetBothValuesTo(const nsCSSValue& aValue) { + mXValue = aValue; + mYValue = aValue; + } + +#ifdef DEBUG + void AppendToString(nsAString& aString, nsCSSProperty aPropName) const; +#endif + + nsCSSValue mXValue; + nsCSSValue mYValue; +}; + struct nsCSSValueListRect { nsCSSValueListRect(void); nsCSSValueListRect(const nsCSSValueListRect& aCopy); @@ -338,8 +379,7 @@ struct nsCSSTable : public nsCSSStruct { // NEW #endif nsCSSValue mBorderCollapse; - nsCSSValue mBorderSpacingX; - nsCSSValue mBorderSpacingY; + nsCSSValuePair mBorderSpacing; nsCSSValue mCaptionSide; nsCSSValue mEmptyCells; @@ -384,8 +424,7 @@ struct nsCSSPage : public nsCSSStruct { // NEW #endif nsCSSValue mMarks; - nsCSSValue mSizeWidth; - nsCSSValue mSizeHeight; + nsCSSValuePair mSize; }; struct nsRuleDataPage : public nsCSSPage { @@ -473,8 +512,7 @@ struct nsCSSAural : public nsCSSStruct { // NEW nsCSSValue mPauseBefore; nsCSSValue mPitch; nsCSSValue mPitchRange; - nsCSSValue mPlayDuring; - nsCSSValue mPlayDuringFlags; + nsCSSValuePair mPlayDuring; // mXValue is URI, mYValue are flags nsCSSValue mRichness; nsCSSValue mSpeak; nsCSSValue mSpeakHeader; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index dbdd5b85c352..4be1af210cd0 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -972,7 +972,41 @@ nsresult nsComputedDOMStyle::GetBorderSpacing(nsIFrame *aFrame, nsIDOMCSSValue** aValue) { - return NS_ERROR_DOM_NOT_SUPPORTED_ERR; + nsDOMCSSValueList *valueList = GetROCSSValueList(PR_FALSE); + NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY); + + const nsStyleTableBorder *border = nsnull; + GetStyleData(eStyleStruct_TableBorder, (const nsStyleStruct*&)border, aFrame); + if (border) { + nsROCSSPrimitiveValue* xSpacing = GetROCSSPrimitiveValue(); + if (!xSpacing) { + delete valueList; + return NS_ERROR_OUT_OF_MEMORY; + } + if (!valueList->AppendCSSValue(xSpacing)) { + delete valueList; + delete xSpacing; + return NS_ERROR_OUT_OF_MEMORY; + } + + nsROCSSPrimitiveValue* ySpacing = GetROCSSPrimitiveValue(); + if (!ySpacing) { + delete valueList; + return NS_ERROR_OUT_OF_MEMORY; + } + if (!valueList->AppendCSSValue(ySpacing)) { + delete valueList; + delete ySpacing; + return NS_ERROR_OUT_OF_MEMORY; + } + + // border-spacing will always be a coord + xSpacing->SetTwips(border->mBorderSpacingX.GetCoordValue()); + ySpacing->SetTwips(border->mBorderSpacingY.GetCoordValue()); + + } + + return CallQueryInterface(valueList, aValue); } nsresult @@ -3522,7 +3556,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength) COMPUTED_STYLE_MAP_ENTRY(border_right_color, BorderRightColor), COMPUTED_STYLE_MAP_ENTRY(border_right_style, BorderRightStyle), COMPUTED_STYLE_MAP_ENTRY(border_right_width, BorderRightWidth), - //// COMPUTED_STYLE_MAP_ENTRY(border_spacing, BorderSpacing), + COMPUTED_STYLE_MAP_ENTRY(border_spacing, BorderSpacing), //// COMPUTED_STYLE_MAP_ENTRY(border_style, BorderStyle), //// COMPUTED_STYLE_MAP_ENTRY(border_top, BorderTop), COMPUTED_STYLE_MAP_ENTRY(border_top_color, BorderTopColor), diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 859041a81fd9..aee9309ad058 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -577,35 +577,43 @@ struct StructCheckData { CheckCallbackFn callback; }; -static void -ExamineRectProperties(const nsCSSRect* aRect, - PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) + +/** + * @param aValue the value being examined + * @param aSpecifiedCount to be incremented by one if the value is specified + * @param aInherited to be incremented by one if the value is set to inherit + */ +inline void +ExamineCSSValue(const nsCSSValue& aValue, + PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) { - if (!aRect) - return; - - if (eCSSUnit_Null != aRect->mLeft.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mLeft.GetUnit()) - aInheritedCount++; + if (aValue.GetUnit() != eCSSUnit_Null) { + ++aSpecifiedCount; + if (aValue.GetUnit() == eCSSUnit_Inherit) { + ++aInheritedCount; + } } +} - if (eCSSUnit_Null != aRect->mTop.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mTop.GetUnit()) - aInheritedCount++; - } +static void +ExamineCSSValuePair(const nsCSSValuePair* aValuePair, + PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) +{ + NS_PRECONDITION(aValuePair, "Must have a value pair"); + + ExamineCSSValue(aValuePair->mXValue, aSpecifiedCount, aInheritedCount); + ExamineCSSValue(aValuePair->mYValue, aSpecifiedCount, aInheritedCount); +} - if (eCSSUnit_Null != aRect->mRight.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mRight.GetUnit()) - aInheritedCount++; - } +static void +ExamineCSSRect(const nsCSSRect* aRect, + PRUint32& aSpecifiedCount, PRUint32& aInheritedCount) +{ + NS_PRECONDITION(aRect, "Must have a rect"); - if (eCSSUnit_Null != aRect->mBottom.GetUnit()) { - aSpecifiedCount++; - if (eCSSUnit_Inherit == aRect->mBottom.GetUnit()) - aInheritedCount++; + NS_FOR_CSS_SIDES(side) { + ExamineCSSValue(aRect->*(nsCSSRect::sides[side]), + aSpecifiedCount, aInheritedCount); } } @@ -840,6 +848,13 @@ RectAtOffset(const nsRuleDataStruct& aRuleDataStruct, size_t aOffset) NS_REINTERPRET_CAST(const char*, &aRuleDataStruct) + aOffset); } +inline const nsCSSValuePair* +ValuePairAtOffset(const nsRuleDataStruct& aRuleDataStruct, size_t aOffset) +{ + return NS_REINTERPRET_CAST(const nsCSSValuePair*, + NS_REINTERPRET_CAST(const char*, &aRuleDataStruct) + aOffset); +} + inline const nsCSSValueList* ValueListAtOffset(const nsRuleDataStruct& aRuleDataStruct, size_t aOffset) { @@ -893,24 +908,23 @@ nsRuleNode::CheckSpecifiedProperties(const nsStyleStructID aSID, switch (prop->type) { case eCSSType_Value: - { - ++total; - const nsCSSValue& value = ValueAtOffset(aRuleDataStruct, prop->offset); - if (eCSSUnit_Null != value.GetUnit()) { - ++specified; - if (eCSSUnit_Inherit == value.GetUnit()) { - ++inherited; - } - } - } + ++total; + ExamineCSSValue(ValueAtOffset(aRuleDataStruct, prop->offset), + specified, inherited); break; case eCSSType_Rect: total += 4; - ExamineRectProperties(RectAtOffset(aRuleDataStruct, prop->offset), - specified, inherited); + ExamineCSSRect(RectAtOffset(aRuleDataStruct, prop->offset), + specified, inherited); break; + case eCSSType_ValuePair: + total += 2; + ExamineCSSValuePair(ValuePairAtOffset(aRuleDataStruct, prop->offset), + specified, inherited); + break; + case eCSSType_ValueList: { ++total; @@ -3827,18 +3841,18 @@ nsRuleNode::ComputeTableBorderData(nsStyleStruct* aStartStruct, nsStyleCoord coord; // border-spacing-x: length, inherit - if (SetCoord(tableData.mBorderSpacingX, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { + if (SetCoord(tableData.mBorderSpacing.mXValue, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { table->mBorderSpacingX = coord.GetCoordValue(); } - else if (eCSSUnit_Inherit == tableData.mBorderSpacingX.GetUnit()) { + else if (eCSSUnit_Inherit == tableData.mBorderSpacing.mXValue.GetUnit()) { inherited = PR_TRUE; table->mBorderSpacingX = parentTable->mBorderSpacingX; } // border-spacing-y: length, inherit - if (SetCoord(tableData.mBorderSpacingY, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { + if (SetCoord(tableData.mBorderSpacing.mYValue, coord, coord, SETCOORD_LENGTH, aContext, mPresContext, inherited)) { table->mBorderSpacingY = coord.GetCoordValue(); } - else if (eCSSUnit_Inherit == tableData.mBorderSpacingY.GetUnit()) { + else if (eCSSUnit_Inherit == tableData.mBorderSpacing.mYValue.GetUnit()) { inherited = PR_TRUE; table->mBorderSpacingY = parentTable->mBorderSpacingY; }