From 474bdc807ee1da3be195171a55970c5e416f4943 Mon Sep 17 00:00:00 2001 From: "dbaron%dbaron.org" Date: Wed, 4 Feb 2004 06:10:56 +0000 Subject: [PATCH] Implement -moz-margin-start, -moz-margin-end, -moz-padding-start, and -moz-padding-end and cascade them correctly. Use them in html.css to improve default styles for lists in RTL documents. b=74880 r+sr=bzbarsky --- content/base/src/nsRuleNode.cpp | 90 ++++++++++++ content/html/style/src/nsCSSDeclaration.cpp | 23 +++- content/html/style/src/nsCSSParser.cpp | 121 ++++++++++++++-- content/html/style/src/nsCSSStruct.cpp | 12 ++ content/html/style/src/nsCSSStruct.h | 12 ++ content/shared/public/nsCSSKeywordList.h | 2 + content/shared/public/nsCSSPropList.h | 46 ++++++- content/shared/public/nsCSSProps.h | 3 + content/shared/public/nsRuleNode.h | 11 ++ content/shared/src/nsCSSProps.cpp | 144 +++++++++++++++++--- dom/public/idl/css/nsIDOMCSS2Properties.idl | 12 ++ layout/base/nsStyleConsts.h | 5 +- layout/base/public/nsStyleConsts.h | 5 +- layout/html/document/src/html.css | 6 +- layout/style/html.css | 6 +- layout/style/nsCSSDeclaration.cpp | 23 +++- layout/style/nsCSSKeywordList.h | 2 + layout/style/nsCSSParser.cpp | 121 ++++++++++++++-- layout/style/nsCSSPropList.h | 46 ++++++- layout/style/nsCSSProps.cpp | 144 +++++++++++++++++--- layout/style/nsCSSProps.h | 3 + layout/style/nsCSSStruct.cpp | 12 ++ layout/style/nsCSSStruct.h | 12 ++ layout/style/nsRuleNode.cpp | 90 ++++++++++++ layout/style/nsRuleNode.h | 11 ++ 25 files changed, 876 insertions(+), 86 deletions(-) diff --git a/content/base/src/nsRuleNode.cpp b/content/base/src/nsRuleNode.cpp index d475807bb8c5..f2c4a4be1476 100644 --- a/content/base/src/nsRuleNode.cpp +++ b/content/base/src/nsRuleNode.cpp @@ -1505,6 +1505,70 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex return nsnull; } +/* + * This function handles cascading of *-left or *-right box properties + * against *-start (which is L for LTR and R for RTL) or *-end (which is + * R for LTR and L for RTL). + * + * Cascading these properties correctly is hard because we need to + * cascade two properties as one, but which two properties depends on a + * third property ('direction'). We solve this by treating each of + * these properties (say, 'margin-start') as a shorthand that sets a + * property containing the value of the property specified + * ('margin-start-value') and sets a pair of properties + * ('margin-left-ltr-source' and 'margin-right-rtl-source') saying which + * of the properties we use. Thus, when we want to compute the value of + * 'margin-left' when 'direction' is 'ltr', we look at the value of + * 'margin-left-ltr-source', which tells us whether to use the highest + * 'margin-left' in the cascade or the highest 'margin-start'. + * + * Finally, since we can compute the normal (*-left and *-right) + * properties in a loop, this function works by assuming the computation + * for those properties has happened as though we have not implemented + * the logical properties (*-start and *-end). It is the responsibility + * of this function to replace the computed values with the values + * computed from the logical properties when needed. + */ +void +nsRuleNode::AdjustLogicalBoxProp(nsStyleContext* aContext, + const nsCSSValue& aLTRSource, + const nsCSSValue& aRTLSource, + const nsCSSValue& aLTRLogicalValue, + const nsCSSValue& aRTLLogicalValue, + const nsStyleSides& aParentRect, + nsStyleSides& aRect, + PRUint8 aSide, + PRInt32 aMask, + PRBool& aInherited) +{ + PRBool LTRlogical = aLTRSource.GetUnit() == eCSSUnit_Enumerated && + aLTRSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL; + PRBool RTLlogical = aRTLSource.GetUnit() == eCSSUnit_Enumerated && + aRTLSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL; + if (LTRlogical || RTLlogical) { + // We can't cache anything on the rule tree if we use any data from + // the style context, since data cached in the rule tree could be + // used with a style context with a different value. + aInherited = PR_TRUE; + PRUint8 dir = aContext->GetStyleVisibility()->mDirection; + + nsStyleCoord parentCoord; + nsStyleCoord coord; + aParentRect.Get(aSide, parentCoord); + if (dir == NS_STYLE_DIRECTION_LTR) { + if (LTRlogical && + SetCoord(aLTRLogicalValue, coord, parentCoord, aMask, aContext, + mPresContext, aInherited)) + aRect.Set(aSide, coord); + } else { + if (RTLlogical && + SetCoord(aRTLLogicalValue, coord, parentCoord, aMask, aContext, + mPresContext, aInherited)) + aRect.Set(aSide, coord); + } + } +} + /* static */ void nsRuleNode::SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext, nscoord aMinFontSize, PRBool aUseDocumentFonts, @@ -3012,6 +3076,19 @@ nsRuleNode::ComputeMarginData(nsStyleStruct* aStartStruct, } } + AdjustLogicalBoxProp(aContext, + marginData.mMarginLeftLTRSource, + marginData.mMarginLeftRTLSource, + marginData.mMarginStart, marginData.mMarginEnd, + parentMargin->mMargin, margin->mMargin, + NS_SIDE_LEFT, SETCOORD_LPAH, inherited); + AdjustLogicalBoxProp(aContext, + marginData.mMarginRightLTRSource, + marginData.mMarginRightRTLSource, + marginData.mMarginEnd, marginData.mMarginStart, + parentMargin->mMargin, margin->mMargin, + NS_SIDE_RIGHT, SETCOORD_LPAH, inherited); + if (inherited) // We inherited, and therefore can't be cached in the rule node. We have to be put right on the // style context. @@ -3229,6 +3306,19 @@ nsRuleNode::ComputePaddingData(nsStyleStruct* aStartStruct, } } + AdjustLogicalBoxProp(aContext, + marginData.mPaddingLeftLTRSource, + marginData.mPaddingLeftRTLSource, + marginData.mPaddingStart, marginData.mPaddingEnd, + parentPadding->mPadding, padding->mPadding, + NS_SIDE_LEFT, SETCOORD_LPH, inherited); + AdjustLogicalBoxProp(aContext, + marginData.mPaddingRightLTRSource, + marginData.mPaddingRightRTLSource, + marginData.mPaddingEnd, marginData.mPaddingStart, + parentPadding->mPadding, padding->mPadding, + NS_SIDE_RIGHT, SETCOORD_LPH, inherited); + if (inherited) // We inherited, and therefore can't be cached in the rule node. We have to be put right on the // style context. diff --git a/content/html/style/src/nsCSSDeclaration.cpp b/content/html/style/src/nsCSSDeclaration.cpp index 1c9c18b6148d..efc2090e8e5d 100644 --- a/content/html/style/src/nsCSSDeclaration.cpp +++ b/content/html/style/src/nsCSSDeclaration.cpp @@ -549,6 +549,21 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, } break; } + case eCSSProperty_margin_left: + case eCSSProperty_margin_right: + case eCSSProperty_margin_start: + case eCSSProperty_margin_end: + case eCSSProperty_padding_left: + case eCSSProperty_padding_right: + case eCSSProperty_padding_start: + case eCSSProperty_padding_end: { + const nsCSSProperty* subprops = + nsCSSProps::SubpropertyEntryFor(aProperty); + NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN, + "not box property with physical vs. logical cascading"); + AppendValueToString(subprops[0], aValue); + break; + } case eCSSProperty_background: { if (AppendValueToString(eCSSProperty_background_color, aValue)) aValue.Append(PRUnichar(' ')); @@ -1032,13 +1047,13 @@ nsCSSDeclaration::ToString(nsAString& aString) const case eCSSProperty_margin_top: marginTop = index+1; break; case eCSSProperty_margin_bottom: marginBottom = index+1; break; - case eCSSProperty_margin_left: marginLeft = index+1; break; - case eCSSProperty_margin_right: marginRight = index+1; break; + case eCSSProperty_margin_left_value: marginLeft = index+1; break; + case eCSSProperty_margin_right_value: marginRight = index+1; break; case eCSSProperty_padding_top: paddingTop = index+1; break; case eCSSProperty_padding_bottom: paddingBottom = index+1; break; - case eCSSProperty_padding_left: paddingLeft = index+1; break; - case eCSSProperty_padding_right: paddingRight = index+1; break; + case eCSSProperty_padding_left_value: paddingLeft = index+1; break; + case eCSSProperty_padding_right_value: paddingRight = index+1; break; case eCSSProperty_background_color: bgColor = index+1; break; case eCSSProperty_background_image: bgImage = index+1; break; diff --git a/content/html/style/src/nsCSSParser.cpp b/content/html/style/src/nsCSSParser.cpp index e6133628d20f..3289b4f96c3b 100644 --- a/content/html/style/src/nsCSSParser.cpp +++ b/content/html/style/src/nsCSSParser.cpp @@ -266,6 +266,9 @@ protected: void AppendValue(nsCSSProperty aPropID, const nsCSSValue& aValue); PRBool ParseBoxProperties(nsresult& aErrorCode, nsCSSRect& aResult, const nsCSSProperty aPropIDs[]); + PRBool ParseDirectionalBoxProperty(nsresult& aErrorCode, + nsCSSProperty aProperty, + PRInt32 aSourceType); PRInt32 ParseChoice(nsresult& aErrorCode, nsCSSValue aValues[], const nsCSSProperty aPropIDs[], PRInt32 aNumIDs); PRBool ParseColor(nsresult& aErrorCode, nsCSSValue& aValue); @@ -3774,6 +3777,26 @@ PRBool CSSParserImpl::ParseBoxProperties(nsresult& aErrorCode, return PR_TRUE; } +PRBool CSSParserImpl::ParseDirectionalBoxProperty(nsresult& aErrorCode, + nsCSSProperty aProperty, + PRInt32 aSourceType) +{ + const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); + NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN, + "not box property with physical vs. logical cascading"); + nsCSSValue value; + if (!ParseSingleValueProperty(aErrorCode, value, subprops[0]) || + !ExpectEndProperty(aErrorCode, PR_TRUE)) + return PR_FALSE; + + AppendValue(subprops[0], value); + nsCSSValue typeVal(aSourceType, eCSSUnit_Enumerated); + AppendValue(subprops[1], typeVal); + AppendValue(subprops[2], typeVal); + aErrorCode = NS_OK; + return PR_TRUE; +} + PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, nsCSSProperty aPropID) { @@ -3846,12 +3869,36 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, return ParseListStyle(aErrorCode); case eCSSProperty_margin: return ParseMargin(aErrorCode); + case eCSSProperty_margin_end: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_end, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_margin_left: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_left, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_margin_right: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_right, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_margin_start: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_start, + NS_BOXPROP_SOURCE_LOGICAL); #ifdef ENABLE_OUTLINE case eCSSProperty__moz_outline: return ParseOutline(aErrorCode); #endif case eCSSProperty_padding: return ParsePadding(aErrorCode); + case eCSSProperty_padding_end: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_end, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_padding_left: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_left, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_padding_right: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_right, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_padding_start: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_start, + NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_pause: return ParsePause(aErrorCode); case eCSSProperty_play_during: @@ -3873,6 +3920,22 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, 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: + case eCSSProperty_margin_start_value: + case eCSSProperty_margin_left_ltr_source: + case eCSSProperty_margin_left_rtl_source: + case eCSSProperty_margin_right_ltr_source: + case eCSSProperty_margin_right_rtl_source: + case eCSSProperty_padding_end_value: + case eCSSProperty_padding_left_value: + case eCSSProperty_padding_right_value: + case eCSSProperty_padding_start_value: + case eCSSProperty_padding_left_ltr_source: + case eCSSProperty_padding_left_rtl_source: + case eCSSProperty_padding_right_ltr_source: + case eCSSProperty_padding_right_rtl_source: // The user can't use these REPORT_UNEXPECTED(NS_LITERAL_STRING("Attempt to use inaccessible property")); return PR_FALSE; @@ -3947,11 +4010,19 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_image_region: case eCSSProperty_list_style: case eCSSProperty_margin: + case eCSSProperty_margin_end: + case eCSSProperty_margin_left: + case eCSSProperty_margin_right: + case eCSSProperty_margin_start: #ifdef ENABLE_OUTLINE case eCSSProperty__moz_outline: case eCSSProperty__moz_outline_radius: #endif case eCSSProperty_padding: + case eCSSProperty_padding_end: + case eCSSProperty_padding_left: + case eCSSProperty_padding_right: + case eCSSProperty_padding_start: case eCSSProperty_pause: case eCSSProperty_play_during: case eCSSProperty_quotes: @@ -3967,6 +4038,14 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, 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: + case eCSSProperty_margin_right_rtl_source: + case eCSSProperty_padding_left_ltr_source: + case eCSSProperty_padding_left_rtl_source: + case eCSSProperty_padding_right_ltr_source: + case eCSSProperty_padding_right_rtl_source: NS_ERROR("not currently parsed here"); return PR_FALSE; @@ -3995,8 +4074,8 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_background_repeat: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundRepeatKTable); - case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: + case eCSSProperty_background_x_position: // for internal use + case eCSSProperty_background_y_position: // for internal use return ParseVariant(aErrorCode, aValue, VARIANT_HKLP, kBackgroundXYPositionKTable); case eCSSProperty_binding: @@ -4172,8 +4251,10 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_list_style_type: return ParseVariant(aErrorCode, aValue, VARIANT_HOK, nsCSSProps::kListStyleKTable); case eCSSProperty_margin_bottom: - case eCSSProperty_margin_left: - case eCSSProperty_margin_right: + case eCSSProperty_margin_end_value: // for internal use + case eCSSProperty_margin_left_value: // for internal use + case eCSSProperty_margin_right_value: // for internal use + case eCSSProperty_margin_start_value: // for internal use case eCSSProperty_margin_top: return ParseVariant(aErrorCode, aValue, VARIANT_AHLP, nsnull); case eCSSProperty_marker_offset: @@ -4206,8 +4287,10 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, return ParseVariant(aErrorCode, aValue, VARIANT_AHK, nsCSSProps::kOverflowKTable); case eCSSProperty_padding_bottom: - case eCSSProperty_padding_left: - case eCSSProperty_padding_right: + case eCSSProperty_padding_end_value: // for internal use + case eCSSProperty_padding_left_value: // for internal use + case eCSSProperty_padding_right_value: // for internal use + case eCSSProperty_padding_start_value: // for internal use case eCSSProperty_padding_top: return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HLP, nsnull); case eCSSProperty_page: @@ -5239,10 +5322,19 @@ PRBool CSSParserImpl::ParseMargin(nsresult& aErrorCode) { static const nsCSSProperty kMarginSideIDs[] = { eCSSProperty_margin_top, - eCSSProperty_margin_right, + eCSSProperty_margin_right_value, eCSSProperty_margin_bottom, - eCSSProperty_margin_left + eCSSProperty_margin_left_value }; + // do this now, in case 4 values weren't specified + mTempData.SetPropertyBit(eCSSProperty_margin_left_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_margin_left_rtl_source); + mTempData.SetPropertyBit(eCSSProperty_margin_right_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_margin_right_rtl_source); + mTempData.mMargin.mMarginLeftLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mMarginLeftRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mMarginRightLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mMarginRightRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); return ParseBoxProperties(aErrorCode, mTempData.mMargin.mMargin, kMarginSideIDs); } @@ -5304,10 +5396,19 @@ PRBool CSSParserImpl::ParsePadding(nsresult& aErrorCode) { static const nsCSSProperty kPaddingSideIDs[] = { eCSSProperty_padding_top, - eCSSProperty_padding_right, + eCSSProperty_padding_right_value, eCSSProperty_padding_bottom, - eCSSProperty_padding_left + eCSSProperty_padding_left_value }; + // do this now, in case 4 values weren't specified + mTempData.SetPropertyBit(eCSSProperty_padding_left_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_padding_left_rtl_source); + mTempData.SetPropertyBit(eCSSProperty_padding_right_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_padding_right_rtl_source); + mTempData.mMargin.mPaddingLeftLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mPaddingLeftRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mPaddingRightLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mPaddingRightRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); return ParseBoxProperties(aErrorCode, mTempData.mMargin.mPadding, kPaddingSideIDs); } diff --git a/content/html/style/src/nsCSSStruct.cpp b/content/html/style/src/nsCSSStruct.cpp index b2ffbd191812..26f305040303 100644 --- a/content/html/style/src/nsCSSStruct.cpp +++ b/content/html/style/src/nsCSSStruct.cpp @@ -537,7 +537,19 @@ nsCSSMargin::nsCSSMargin(void) nsCSSMargin::nsCSSMargin(const nsCSSMargin& aCopy) : mMargin(aCopy.mMargin), + mMarginStart(aCopy.mMarginStart), + mMarginEnd(aCopy.mMarginEnd), + mMarginLeftLTRSource(aCopy.mMarginLeftLTRSource), + mMarginLeftRTLSource(aCopy.mMarginLeftRTLSource), + mMarginRightLTRSource(aCopy.mMarginRightLTRSource), + mMarginRightRTLSource(aCopy.mMarginRightRTLSource), mPadding(aCopy.mPadding), + mPaddingStart(aCopy.mPaddingStart), + mPaddingEnd(aCopy.mPaddingEnd), + mPaddingLeftLTRSource(aCopy.mPaddingLeftLTRSource), + mPaddingLeftRTLSource(aCopy.mPaddingLeftRTLSource), + mPaddingRightLTRSource(aCopy.mPaddingRightLTRSource), + mPaddingRightRTLSource(aCopy.mPaddingRightRTLSource), mBorderWidth(aCopy.mBorderWidth), mBorderColor(aCopy.mBorderColor), mBorderColors(aCopy.mBorderColors), diff --git a/content/html/style/src/nsCSSStruct.h b/content/html/style/src/nsCSSStruct.h index e2c0fc634a56..817c2cf15a69 100644 --- a/content/html/style/src/nsCSSStruct.h +++ b/content/html/style/src/nsCSSStruct.h @@ -245,7 +245,19 @@ struct nsCSSMargin : public nsCSSStruct { #endif nsCSSRect mMargin; + nsCSSValue mMarginStart; + nsCSSValue mMarginEnd; + nsCSSValue mMarginLeftLTRSource; + nsCSSValue mMarginLeftRTLSource; + nsCSSValue mMarginRightLTRSource; + nsCSSValue mMarginRightRTLSource; nsCSSRect mPadding; + nsCSSValue mPaddingStart; + nsCSSValue mPaddingEnd; + nsCSSValue mPaddingLeftLTRSource; + nsCSSValue mPaddingLeftRTLSource; + nsCSSValue mPaddingRightLTRSource; + nsCSSValue mPaddingRightRTLSource; nsCSSRect mBorderWidth; nsCSSRect mBorderColor; nsCSSValueListRect mBorderColors; diff --git a/content/shared/public/nsCSSKeywordList.h b/content/shared/public/nsCSSKeywordList.h index 97d221f9e328..4c31c05aeb6e 100644 --- a/content/shared/public/nsCSSKeywordList.h +++ b/content/shared/public/nsCSSKeywordList.h @@ -293,6 +293,7 @@ CSS_KEY(level, level) CSS_KEY(lighter, lighter) CSS_KEY(line-through, line_through) CSS_KEY(list-item, list_item) +CSS_KEY(logical, logical) CSS_KEY(loud, loud) CSS_KEY(low, low) CSS_KEY(lower, lower) @@ -332,6 +333,7 @@ CSS_KEY(overline, overline) CSS_KEY(padding, padding) CSS_KEY(padding-box, padding_box) CSS_KEY(pc, pc) +CSS_KEY(physical, physical) CSS_KEY(pointer, pointer) CSS_KEY(portrait, portrait) CSS_KEY(pre, pre) diff --git a/content/shared/public/nsCSSPropList.h b/content/shared/public/nsCSSPropList.h index 0e3d4e7b0101..799de30ec9c0 100644 --- a/content/shared/public/nsCSSPropList.h +++ b/content/shared/public/nsCSSPropList.h @@ -353,8 +353,26 @@ CSS_PROP_LIST(list-style-position, list_style_position, ListStylePosition, List, CSS_PROP_LIST(list-style-type, list_style_type, ListStyleType, List, mType, eCSSType_Value, PR_FALSE) CSS_PROP_SHORTHAND(margin, margin, Margin) CSS_PROP_MARGIN(margin-bottom, margin_bottom, MarginBottom, Margin, mMargin.mBottom, eCSSType_Value, PR_TRUE) -CSS_PROP_MARGIN(margin-left, margin_left, MarginLeft, Margin, mMargin.mLeft, eCSSType_Value, PR_TRUE) -CSS_PROP_MARGIN(margin-right, margin_right, MarginRight, Margin, mMargin.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_SHORTHAND(-moz-margin-end, margin_end, MozMarginEnd) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-end-value, margin_end_value, X, Margin, mMarginEnd, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(margin-left, margin_left, MarginLeft) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-left-value, margin_left_value, X, Margin, mMargin.mLeft, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-left-ltr-source, margin_left_ltr_source, X, Margin, mMarginLeftLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-left-rtl-source, margin_left_rtl_source, X, Margin, mMarginLeftRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(margin-right, margin_right, MarginRight) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-right-value, margin_right_value, X, Margin, mMargin.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-right-ltr-source, margin_right_ltr_source, X, Margin, mMarginRightLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-right-rtl-source, margin_right_rtl_source, X, Margin, mMarginRightRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(-moz-margin-start, margin_start, MozMarginStart) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-start-value, margin_start_value, X, Margin, mMarginStart, eCSSType_Value, PR_TRUE) +#endif CSS_PROP_MARGIN(margin-top, margin_top, MarginTop, Margin, mMargin.mTop, eCSSType_Value, PR_TRUE) CSS_PROP_CONTENT(marker-offset, marker_offset, MarkerOffset, Content, mMarkerOffset, eCSSType_Value, PR_TRUE) CSS_PROP_BACKENDONLY(marks, marks, Marks, Page, mMarks, eCSSType_Value, PR_FALSE) @@ -375,8 +393,26 @@ CSS_PROP_OUTLINE(-moz-outline-width, _moz_outline_width, MozOutlineWidth, Margin CSS_PROP_DISPLAY(overflow, overflow, Overflow, Display, mOverflow, eCSSType_Value, PR_FALSE) CSS_PROP_SHORTHAND(padding, padding, Padding) CSS_PROP_PADDING(padding-bottom, padding_bottom, PaddingBottom, Margin, mPadding.mBottom, eCSSType_Value, PR_TRUE) -CSS_PROP_PADDING(padding-left, padding_left, PaddingLeft, Margin, mPadding.mLeft, eCSSType_Value, PR_TRUE) -CSS_PROP_PADDING(padding-right, padding_right, PaddingRight, Margin, mPadding.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_SHORTHAND(-moz-padding-end, padding_end, MozPaddingEnd) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-end-value, padding_end_value, X, Margin, mPaddingEnd, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(padding-left, padding_left, PaddingLeft) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-left-value, padding_left_value, X, Margin, mPadding.mLeft, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-left-ltr-source, padding_left_ltr_source, X, Margin, mPaddingLeftLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-left-rtl-source, padding_left_rtl_source, X, Margin, mPaddingLeftRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(padding-right, padding_right, PaddingRight) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-right-value, padding_right_value, X, Margin, mPadding.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-right-ltr-source, padding_right_ltr_source, X, Margin, mPaddingRightLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-right-rtl-source, padding_right_rtl_source, X, Margin, mPaddingRightRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(-moz-padding-start, padding_start, MozPaddingStart) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-start-value, padding_start_value, X, Margin, mPaddingStart, eCSSType_Value, PR_TRUE) +#endif CSS_PROP_PADDING(padding-top, padding_top, PaddingTop, Margin, mPadding.mTop, eCSSType_Value, PR_TRUE) CSS_PROP_BACKENDONLY(page, page, Page, Breaks, mPage, eCSSType_Value, PR_FALSE) CSS_PROP_DISPLAY(page-break-after, page_break_after, PageBreakAfter, Display, mBreakAfter, eCSSType_Value, PR_FALSE) // temp fix for bug 24000 @@ -459,7 +495,7 @@ CSS_PROP_SVG(stroke-width, stroke_width, StrokeWidth, SVG, mStrokeWidth, eCSSTyp // the style structs but not in the nsCSS* structs should define // |CSS_PROP_INCLUDE_NOT_CSS|. (Some of these are also in nsRuleData*, // and a distinction might be needed at some point.) -// The first 4 parameters don't matter, but some compilers don't like +// The first 3 parameters don't matter, but some compilers don't like // empty arguments to macros. #ifdef CSS_PROP_INCLUDE_NOT_CSS CSS_PROP_VISIBILITY(X, X, X, Display, mLang, eCSSType_Value, PR_FALSE) diff --git a/content/shared/public/nsCSSProps.h b/content/shared/public/nsCSSProps.h index 3e79dede4a3b..4ece91eb3804 100644 --- a/content/shared/public/nsCSSProps.h +++ b/content/shared/public/nsCSSProps.h @@ -105,6 +105,8 @@ public: static const PRInt32 kBackgroundInlinePolicyKTable[]; static const PRInt32 kBackgroundOriginKTable[]; static const PRInt32 kBackgroundRepeatKTable[]; + static const PRInt32 kBackgroundXPositionKTable[]; + static const PRInt32 kBackgroundYPositionKTable[]; static const PRInt32 kBorderCollapseKTable[]; static const PRInt32 kBorderColorKTable[]; static const PRInt32 kBorderStyleKTable[]; @@ -118,6 +120,7 @@ public: static const PRInt32 kStrokeLinecapKTable[]; static const PRInt32 kStrokeLinejoinKTable[]; #endif + static const PRInt32 kBoxPropSourceKTable[]; static const PRInt32 kBoxSizingKTable[]; static const PRInt32 kCaptionSideKTable[]; static const PRInt32 kClearKTable[]; diff --git a/content/shared/public/nsRuleNode.h b/content/shared/public/nsRuleNode.h index 22fdfd7ab19c..59ece654ccb9 100644 --- a/content/shared/public/nsRuleNode.h +++ b/content/shared/public/nsRuleNode.h @@ -497,6 +497,17 @@ protected: const nsRuleDataFont& aFontData, PRUint8 aGenericFontID, nscoord aMinFontSize, PRBool aUseDocumentFonts, nsStyleFont* aFont); + + void AdjustLogicalBoxProp(nsStyleContext* aContext, + const nsCSSValue& aLTRSource, + const nsCSSValue& aRTLSource, + const nsCSSValue& aLTRLogicalValue, + const nsCSSValue& aRTLLogicalValue, + const nsStyleSides& aParentRect, + nsStyleSides& aRect, + PRUint8 aSide, + PRInt32 aMask, + PRBool& aInherited); inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID, const nsRuleDataStruct& aRuleDataStruct); diff --git a/content/shared/src/nsCSSProps.cpp b/content/shared/src/nsCSSProps.cpp index 695c6053c7f2..53f25996221e 100644 --- a/content/shared/src/nsCSSProps.cpp +++ b/content/shared/src/nsCSSProps.cpp @@ -266,6 +266,20 @@ const PRInt32 nsCSSProps::kBackgroundRepeatKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBackgroundXPositionKTable[] = { + eCSSKeyword_left, 0, + eCSSKeyword_center, 50, + eCSSKeyword_right, 100, + -1,-1 +}; + +const PRInt32 nsCSSProps::kBackgroundYPositionKTable[] = { + eCSSKeyword_top, 0, + eCSSKeyword_center, 50, + eCSSKeyword_bottom, 100, + -1,-1 +}; + const PRInt32 nsCSSProps::kBorderCollapseKTable[] = { eCSSKeyword_collapse, NS_STYLE_BORDER_COLLAPSE, eCSSKeyword_separate, NS_STYLE_BORDER_SEPARATE, @@ -301,6 +315,12 @@ const PRInt32 nsCSSProps::kBorderWidthKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBoxPropSourceKTable[] = { + eCSSKeyword_physical, NS_BOXPROP_SOURCE_PHYSICAL, + eCSSKeyword_logical, NS_BOXPROP_SOURCE_LOGICAL, + -1,-1 +}; + const PRInt32 nsCSSProps::kBoxSizingKTable[] = { eCSSKeyword_content_box, NS_STYLE_BOX_SIZING_CONTENT, eCSSKeyword_border_box, NS_STYLE_BOX_SIZING_BORDER, @@ -917,25 +937,10 @@ nsCSSProps::SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) } // XXX TODO These table names should be additional parameters of the -// properties below in nsCSSPropList.h (and the two below should be like -// the rest). +// properties below in nsCSSPropList.h. const nsAFlatCString& nsCSSProps::LookupPropertyValue(nsCSSProperty aProp, PRInt32 aValue) { -static const PRInt32 kBackgroundXPositionKTable[] = { - eCSSKeyword_left, 0, - eCSSKeyword_center, 50, - eCSSKeyword_right, 100, - -1,-1 -}; - -static const PRInt32 kBackgroundYPositionKTable[] = { - eCSSKeyword_top, 0, - eCSSKeyword_center, 50, - eCSSKeyword_bottom, 100, - -1,-1 -}; - switch (aProp) { case eCSSProperty__moz_border_radius: @@ -1157,12 +1162,24 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty_margin: case eCSSProperty_margin_bottom: + case eCSSProperty_margin_end: + case eCSSProperty_margin_end_value: case eCSSProperty_margin_left: + case eCSSProperty_margin_left_value: case eCSSProperty_margin_right: + case eCSSProperty_margin_right_value: + case eCSSProperty_margin_start: + case eCSSProperty_margin_start_value: case eCSSProperty_margin_top: case eCSSProperty_marker_offset: break; + case eCSSProperty_margin_left_ltr_source: + case eCSSProperty_margin_left_rtl_source: + case eCSSProperty_margin_right_ltr_source: + case eCSSProperty_margin_right_rtl_source: + return SearchKeywordTable(aValue, kBoxPropSourceKTable); + case eCSSProperty_marks: return SearchKeywordTable(aValue, kPageMarksKTable); @@ -1191,12 +1208,24 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty_padding: case eCSSProperty_padding_bottom: + case eCSSProperty_padding_end: + case eCSSProperty_padding_end_value: case eCSSProperty_padding_left: + case eCSSProperty_padding_left_value: case eCSSProperty_padding_right: + case eCSSProperty_padding_right_value: + case eCSSProperty_padding_start: + case eCSSProperty_padding_start_value: case eCSSProperty_padding_top: case eCSSProperty_page: break; + case eCSSProperty_padding_left_ltr_source: + case eCSSProperty_padding_left_rtl_source: + case eCSSProperty_padding_right_ltr_source: + case eCSSProperty_padding_right_rtl_source: + return SearchKeywordTable(aValue, kBoxPropSourceKTable); + case eCSSProperty_page_break_before: case eCSSProperty_page_break_after: return SearchKeywordTable(aValue, kPageBreakKTable); @@ -1551,12 +1580,50 @@ static const nsCSSProperty gListStyleSubpropTable[] = { static const nsCSSProperty gMarginSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_margin_top, - eCSSProperty_margin_right, + eCSSProperty_margin_right_value, eCSSProperty_margin_bottom, - eCSSProperty_margin_left, + eCSSProperty_margin_left_value, + // extras: + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_right_rtl_source, eCSSProperty_UNKNOWN }; +static const nsCSSProperty gMarginLeftSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_left_value, + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMarginRightSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_right_value, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozMarginStartSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_start_value, + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozMarginEndSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_end_value, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_UNKNOWN +}; + + static const nsCSSProperty gMozOutlineSubpropTable[] = { // nsCSSDeclaration.cpp outputs the subproperties in this order. eCSSProperty__moz_outline_color, @@ -1568,9 +1635,46 @@ static const nsCSSProperty gMozOutlineSubpropTable[] = { static const nsCSSProperty gPaddingSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_padding_top, - eCSSProperty_padding_right, + eCSSProperty_padding_right_value, eCSSProperty_padding_bottom, - eCSSProperty_padding_left, + eCSSProperty_padding_left_value, + // extras: + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_left_rtl_source, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingLeftSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_left_value, + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_left_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingRightSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_right_value, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozPaddingStartSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_start_value, + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozPaddingEndSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_end_value, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_left_rtl_source, eCSSProperty_UNKNOWN }; diff --git a/dom/public/idl/css/nsIDOMCSS2Properties.idl b/dom/public/idl/css/nsIDOMCSS2Properties.idl index 931a8c546d0d..590971738aa2 100644 --- a/dom/public/idl/css/nsIDOMCSS2Properties.idl +++ b/dom/public/idl/css/nsIDOMCSS2Properties.idl @@ -495,6 +495,12 @@ interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties attribute DOMString MozKeyEquivalent; // raises(DOMException) on setting + attribute DOMString MozMarginEnd; + // raises(DOMException) on setting + + attribute DOMString MozMarginStart; + // raises(DOMException) on setting + attribute DOMString MozOpacity; // raises(DOMException) on setting @@ -525,6 +531,12 @@ interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties attribute DOMString MozOutlineWidth; // raises(DOMException) on setting + attribute DOMString MozPaddingEnd; + // raises(DOMException) on setting + + attribute DOMString MozPaddingStart; + // raises(DOMException) on setting + attribute DOMString MozResizer; // raises(DOMException) on setting diff --git a/layout/base/nsStyleConsts.h b/layout/base/nsStyleConsts.h index 56124e2147ad..28aabea1704b 100644 --- a/layout/base/nsStyleConsts.h +++ b/layout/base/nsStyleConsts.h @@ -41,12 +41,15 @@ // XXX fold this into nsStyleContext and group by nsStyleXXX struct -// Indicies into border/padding/margin arrays +// Indices into border/padding/margin arrays #define NS_SIDE_TOP 0 #define NS_SIDE_RIGHT 1 #define NS_SIDE_BOTTOM 2 #define NS_SIDE_LEFT 3 +// {margin,padding}-{left,right}-{ltr,rtl}-source +#define NS_BOXPROP_SOURCE_PHYSICAL 0 +#define NS_BOXPROP_SOURCE_LOGICAL 1 // box-sizing #define NS_STYLE_BOX_SIZING_CONTENT 0 diff --git a/layout/base/public/nsStyleConsts.h b/layout/base/public/nsStyleConsts.h index 56124e2147ad..28aabea1704b 100644 --- a/layout/base/public/nsStyleConsts.h +++ b/layout/base/public/nsStyleConsts.h @@ -41,12 +41,15 @@ // XXX fold this into nsStyleContext and group by nsStyleXXX struct -// Indicies into border/padding/margin arrays +// Indices into border/padding/margin arrays #define NS_SIDE_TOP 0 #define NS_SIDE_RIGHT 1 #define NS_SIDE_BOTTOM 2 #define NS_SIDE_LEFT 3 +// {margin,padding}-{left,right}-{ltr,rtl}-source +#define NS_BOXPROP_SOURCE_PHYSICAL 0 +#define NS_BOXPROP_SOURCE_LOGICAL 1 // box-sizing #define NS_STYLE_BOX_SIZING_CONTENT 0 diff --git a/layout/html/document/src/html.css b/layout/html/document/src/html.css index 957119ac633a..f992dbc1bd3d 100644 --- a/layout/html/document/src/html.css +++ b/layout/html/document/src/html.css @@ -55,7 +55,7 @@ p, dl, multicol { dd { display: block; - margin-left: 40px; + -moz-margin-start: 40px; } blockquote { @@ -307,7 +307,7 @@ ul, menu, dir { display: block; list-style-type: disc; margin: 1em 0; - padding-left: 40px; + -moz-padding-start: 40px; -moz-counter-reset: -html-counter 0; } @@ -315,7 +315,7 @@ ol { display: block; list-style-type: decimal; margin: 1em 0; - padding-left: 40px; + -moz-padding-start: 40px; -moz-counter-reset: -html-counter 0; } diff --git a/layout/style/html.css b/layout/style/html.css index 957119ac633a..f992dbc1bd3d 100644 --- a/layout/style/html.css +++ b/layout/style/html.css @@ -55,7 +55,7 @@ p, dl, multicol { dd { display: block; - margin-left: 40px; + -moz-margin-start: 40px; } blockquote { @@ -307,7 +307,7 @@ ul, menu, dir { display: block; list-style-type: disc; margin: 1em 0; - padding-left: 40px; + -moz-padding-start: 40px; -moz-counter-reset: -html-counter 0; } @@ -315,7 +315,7 @@ ol { display: block; list-style-type: decimal; margin: 1em 0; - padding-left: 40px; + -moz-padding-start: 40px; -moz-counter-reset: -html-counter 0; } diff --git a/layout/style/nsCSSDeclaration.cpp b/layout/style/nsCSSDeclaration.cpp index 1c9c18b6148d..efc2090e8e5d 100644 --- a/layout/style/nsCSSDeclaration.cpp +++ b/layout/style/nsCSSDeclaration.cpp @@ -549,6 +549,21 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty, } break; } + case eCSSProperty_margin_left: + case eCSSProperty_margin_right: + case eCSSProperty_margin_start: + case eCSSProperty_margin_end: + case eCSSProperty_padding_left: + case eCSSProperty_padding_right: + case eCSSProperty_padding_start: + case eCSSProperty_padding_end: { + const nsCSSProperty* subprops = + nsCSSProps::SubpropertyEntryFor(aProperty); + NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN, + "not box property with physical vs. logical cascading"); + AppendValueToString(subprops[0], aValue); + break; + } case eCSSProperty_background: { if (AppendValueToString(eCSSProperty_background_color, aValue)) aValue.Append(PRUnichar(' ')); @@ -1032,13 +1047,13 @@ nsCSSDeclaration::ToString(nsAString& aString) const case eCSSProperty_margin_top: marginTop = index+1; break; case eCSSProperty_margin_bottom: marginBottom = index+1; break; - case eCSSProperty_margin_left: marginLeft = index+1; break; - case eCSSProperty_margin_right: marginRight = index+1; break; + case eCSSProperty_margin_left_value: marginLeft = index+1; break; + case eCSSProperty_margin_right_value: marginRight = index+1; break; case eCSSProperty_padding_top: paddingTop = index+1; break; case eCSSProperty_padding_bottom: paddingBottom = index+1; break; - case eCSSProperty_padding_left: paddingLeft = index+1; break; - case eCSSProperty_padding_right: paddingRight = index+1; break; + case eCSSProperty_padding_left_value: paddingLeft = index+1; break; + case eCSSProperty_padding_right_value: paddingRight = index+1; break; case eCSSProperty_background_color: bgColor = index+1; break; case eCSSProperty_background_image: bgImage = index+1; break; diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index 97d221f9e328..4c31c05aeb6e 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -293,6 +293,7 @@ CSS_KEY(level, level) CSS_KEY(lighter, lighter) CSS_KEY(line-through, line_through) CSS_KEY(list-item, list_item) +CSS_KEY(logical, logical) CSS_KEY(loud, loud) CSS_KEY(low, low) CSS_KEY(lower, lower) @@ -332,6 +333,7 @@ CSS_KEY(overline, overline) CSS_KEY(padding, padding) CSS_KEY(padding-box, padding_box) CSS_KEY(pc, pc) +CSS_KEY(physical, physical) CSS_KEY(pointer, pointer) CSS_KEY(portrait, portrait) CSS_KEY(pre, pre) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index e6133628d20f..3289b4f96c3b 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -266,6 +266,9 @@ protected: void AppendValue(nsCSSProperty aPropID, const nsCSSValue& aValue); PRBool ParseBoxProperties(nsresult& aErrorCode, nsCSSRect& aResult, const nsCSSProperty aPropIDs[]); + PRBool ParseDirectionalBoxProperty(nsresult& aErrorCode, + nsCSSProperty aProperty, + PRInt32 aSourceType); PRInt32 ParseChoice(nsresult& aErrorCode, nsCSSValue aValues[], const nsCSSProperty aPropIDs[], PRInt32 aNumIDs); PRBool ParseColor(nsresult& aErrorCode, nsCSSValue& aValue); @@ -3774,6 +3777,26 @@ PRBool CSSParserImpl::ParseBoxProperties(nsresult& aErrorCode, return PR_TRUE; } +PRBool CSSParserImpl::ParseDirectionalBoxProperty(nsresult& aErrorCode, + nsCSSProperty aProperty, + PRInt32 aSourceType) +{ + const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(aProperty); + NS_ASSERTION(subprops[3] == eCSSProperty_UNKNOWN, + "not box property with physical vs. logical cascading"); + nsCSSValue value; + if (!ParseSingleValueProperty(aErrorCode, value, subprops[0]) || + !ExpectEndProperty(aErrorCode, PR_TRUE)) + return PR_FALSE; + + AppendValue(subprops[0], value); + nsCSSValue typeVal(aSourceType, eCSSUnit_Enumerated); + AppendValue(subprops[1], typeVal); + AppendValue(subprops[2], typeVal); + aErrorCode = NS_OK; + return PR_TRUE; +} + PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, nsCSSProperty aPropID) { @@ -3846,12 +3869,36 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, return ParseListStyle(aErrorCode); case eCSSProperty_margin: return ParseMargin(aErrorCode); + case eCSSProperty_margin_end: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_end, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_margin_left: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_left, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_margin_right: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_right, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_margin_start: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_margin_start, + NS_BOXPROP_SOURCE_LOGICAL); #ifdef ENABLE_OUTLINE case eCSSProperty__moz_outline: return ParseOutline(aErrorCode); #endif case eCSSProperty_padding: return ParsePadding(aErrorCode); + case eCSSProperty_padding_end: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_end, + NS_BOXPROP_SOURCE_LOGICAL); + case eCSSProperty_padding_left: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_left, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_padding_right: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_right, + NS_BOXPROP_SOURCE_PHYSICAL); + case eCSSProperty_padding_start: + return ParseDirectionalBoxProperty(aErrorCode, eCSSProperty_padding_start, + NS_BOXPROP_SOURCE_LOGICAL); case eCSSProperty_pause: return ParsePause(aErrorCode); case eCSSProperty_play_during: @@ -3873,6 +3920,22 @@ PRBool CSSParserImpl::ParseProperty(nsresult& aErrorCode, 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: + case eCSSProperty_margin_start_value: + case eCSSProperty_margin_left_ltr_source: + case eCSSProperty_margin_left_rtl_source: + case eCSSProperty_margin_right_ltr_source: + case eCSSProperty_margin_right_rtl_source: + case eCSSProperty_padding_end_value: + case eCSSProperty_padding_left_value: + case eCSSProperty_padding_right_value: + case eCSSProperty_padding_start_value: + case eCSSProperty_padding_left_ltr_source: + case eCSSProperty_padding_left_rtl_source: + case eCSSProperty_padding_right_ltr_source: + case eCSSProperty_padding_right_rtl_source: // The user can't use these REPORT_UNEXPECTED(NS_LITERAL_STRING("Attempt to use inaccessible property")); return PR_FALSE; @@ -3947,11 +4010,19 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_image_region: case eCSSProperty_list_style: case eCSSProperty_margin: + case eCSSProperty_margin_end: + case eCSSProperty_margin_left: + case eCSSProperty_margin_right: + case eCSSProperty_margin_start: #ifdef ENABLE_OUTLINE case eCSSProperty__moz_outline: case eCSSProperty__moz_outline_radius: #endif case eCSSProperty_padding: + case eCSSProperty_padding_end: + case eCSSProperty_padding_left: + case eCSSProperty_padding_right: + case eCSSProperty_padding_start: case eCSSProperty_pause: case eCSSProperty_play_during: case eCSSProperty_quotes: @@ -3967,6 +4038,14 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, 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: + case eCSSProperty_margin_right_rtl_source: + case eCSSProperty_padding_left_ltr_source: + case eCSSProperty_padding_left_rtl_source: + case eCSSProperty_padding_right_ltr_source: + case eCSSProperty_padding_right_rtl_source: NS_ERROR("not currently parsed here"); return PR_FALSE; @@ -3995,8 +4074,8 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_background_repeat: return ParseVariant(aErrorCode, aValue, VARIANT_HK, nsCSSProps::kBackgroundRepeatKTable); - case eCSSProperty_background_x_position: - case eCSSProperty_background_y_position: + case eCSSProperty_background_x_position: // for internal use + case eCSSProperty_background_y_position: // for internal use return ParseVariant(aErrorCode, aValue, VARIANT_HKLP, kBackgroundXYPositionKTable); case eCSSProperty_binding: @@ -4172,8 +4251,10 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_list_style_type: return ParseVariant(aErrorCode, aValue, VARIANT_HOK, nsCSSProps::kListStyleKTable); case eCSSProperty_margin_bottom: - case eCSSProperty_margin_left: - case eCSSProperty_margin_right: + case eCSSProperty_margin_end_value: // for internal use + case eCSSProperty_margin_left_value: // for internal use + case eCSSProperty_margin_right_value: // for internal use + case eCSSProperty_margin_start_value: // for internal use case eCSSProperty_margin_top: return ParseVariant(aErrorCode, aValue, VARIANT_AHLP, nsnull); case eCSSProperty_marker_offset: @@ -4206,8 +4287,10 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, return ParseVariant(aErrorCode, aValue, VARIANT_AHK, nsCSSProps::kOverflowKTable); case eCSSProperty_padding_bottom: - case eCSSProperty_padding_left: - case eCSSProperty_padding_right: + case eCSSProperty_padding_end_value: // for internal use + case eCSSProperty_padding_left_value: // for internal use + case eCSSProperty_padding_right_value: // for internal use + case eCSSProperty_padding_start_value: // for internal use case eCSSProperty_padding_top: return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HLP, nsnull); case eCSSProperty_page: @@ -5239,10 +5322,19 @@ PRBool CSSParserImpl::ParseMargin(nsresult& aErrorCode) { static const nsCSSProperty kMarginSideIDs[] = { eCSSProperty_margin_top, - eCSSProperty_margin_right, + eCSSProperty_margin_right_value, eCSSProperty_margin_bottom, - eCSSProperty_margin_left + eCSSProperty_margin_left_value }; + // do this now, in case 4 values weren't specified + mTempData.SetPropertyBit(eCSSProperty_margin_left_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_margin_left_rtl_source); + mTempData.SetPropertyBit(eCSSProperty_margin_right_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_margin_right_rtl_source); + mTempData.mMargin.mMarginLeftLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mMarginLeftRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mMarginRightLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mMarginRightRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); return ParseBoxProperties(aErrorCode, mTempData.mMargin.mMargin, kMarginSideIDs); } @@ -5304,10 +5396,19 @@ PRBool CSSParserImpl::ParsePadding(nsresult& aErrorCode) { static const nsCSSProperty kPaddingSideIDs[] = { eCSSProperty_padding_top, - eCSSProperty_padding_right, + eCSSProperty_padding_right_value, eCSSProperty_padding_bottom, - eCSSProperty_padding_left + eCSSProperty_padding_left_value }; + // do this now, in case 4 values weren't specified + mTempData.SetPropertyBit(eCSSProperty_padding_left_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_padding_left_rtl_source); + mTempData.SetPropertyBit(eCSSProperty_padding_right_ltr_source); + mTempData.SetPropertyBit(eCSSProperty_padding_right_rtl_source); + mTempData.mMargin.mPaddingLeftLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mPaddingLeftRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mPaddingRightLTRSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); + mTempData.mMargin.mPaddingRightRTLSource.SetIntValue(NS_BOXPROP_SOURCE_PHYSICAL, eCSSUnit_Enumerated); return ParseBoxProperties(aErrorCode, mTempData.mMargin.mPadding, kPaddingSideIDs); } diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 0e3d4e7b0101..799de30ec9c0 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -353,8 +353,26 @@ CSS_PROP_LIST(list-style-position, list_style_position, ListStylePosition, List, CSS_PROP_LIST(list-style-type, list_style_type, ListStyleType, List, mType, eCSSType_Value, PR_FALSE) CSS_PROP_SHORTHAND(margin, margin, Margin) CSS_PROP_MARGIN(margin-bottom, margin_bottom, MarginBottom, Margin, mMargin.mBottom, eCSSType_Value, PR_TRUE) -CSS_PROP_MARGIN(margin-left, margin_left, MarginLeft, Margin, mMargin.mLeft, eCSSType_Value, PR_TRUE) -CSS_PROP_MARGIN(margin-right, margin_right, MarginRight, Margin, mMargin.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_SHORTHAND(-moz-margin-end, margin_end, MozMarginEnd) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-end-value, margin_end_value, X, Margin, mMarginEnd, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(margin-left, margin_left, MarginLeft) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-left-value, margin_left_value, X, Margin, mMargin.mLeft, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-left-ltr-source, margin_left_ltr_source, X, Margin, mMarginLeftLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-left-rtl-source, margin_left_rtl_source, X, Margin, mMarginLeftRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(margin-right, margin_right, MarginRight) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-right-value, margin_right_value, X, Margin, mMargin.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-right-ltr-source, margin_right_ltr_source, X, Margin, mMarginRightLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_MARGIN(margin-right-rtl-source, margin_right_rtl_source, X, Margin, mMarginRightRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(-moz-margin-start, margin_start, MozMarginStart) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_MARGIN(margin-start-value, margin_start_value, X, Margin, mMarginStart, eCSSType_Value, PR_TRUE) +#endif CSS_PROP_MARGIN(margin-top, margin_top, MarginTop, Margin, mMargin.mTop, eCSSType_Value, PR_TRUE) CSS_PROP_CONTENT(marker-offset, marker_offset, MarkerOffset, Content, mMarkerOffset, eCSSType_Value, PR_TRUE) CSS_PROP_BACKENDONLY(marks, marks, Marks, Page, mMarks, eCSSType_Value, PR_FALSE) @@ -375,8 +393,26 @@ CSS_PROP_OUTLINE(-moz-outline-width, _moz_outline_width, MozOutlineWidth, Margin CSS_PROP_DISPLAY(overflow, overflow, Overflow, Display, mOverflow, eCSSType_Value, PR_FALSE) CSS_PROP_SHORTHAND(padding, padding, Padding) CSS_PROP_PADDING(padding-bottom, padding_bottom, PaddingBottom, Margin, mPadding.mBottom, eCSSType_Value, PR_TRUE) -CSS_PROP_PADDING(padding-left, padding_left, PaddingLeft, Margin, mPadding.mLeft, eCSSType_Value, PR_TRUE) -CSS_PROP_PADDING(padding-right, padding_right, PaddingRight, Margin, mPadding.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_SHORTHAND(-moz-padding-end, padding_end, MozPaddingEnd) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-end-value, padding_end_value, X, Margin, mPaddingEnd, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(padding-left, padding_left, PaddingLeft) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-left-value, padding_left_value, X, Margin, mPadding.mLeft, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-left-ltr-source, padding_left_ltr_source, X, Margin, mPaddingLeftLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-left-rtl-source, padding_left_rtl_source, X, Margin, mPaddingLeftRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(padding-right, padding_right, PaddingRight) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-right-value, padding_right_value, X, Margin, mPadding.mRight, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-right-ltr-source, padding_right_ltr_source, X, Margin, mPaddingRightLTRSource, eCSSType_Value, PR_TRUE) +CSS_PROP_PADDING(padding-right-rtl-source, padding_right_rtl_source, X, Margin, mPaddingRightRTLSource, eCSSType_Value, PR_TRUE) +#endif +CSS_PROP_SHORTHAND(-moz-padding-start, padding_start, MozPaddingStart) +#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL +CSS_PROP_PADDING(padding-start-value, padding_start_value, X, Margin, mPaddingStart, eCSSType_Value, PR_TRUE) +#endif CSS_PROP_PADDING(padding-top, padding_top, PaddingTop, Margin, mPadding.mTop, eCSSType_Value, PR_TRUE) CSS_PROP_BACKENDONLY(page, page, Page, Breaks, mPage, eCSSType_Value, PR_FALSE) CSS_PROP_DISPLAY(page-break-after, page_break_after, PageBreakAfter, Display, mBreakAfter, eCSSType_Value, PR_FALSE) // temp fix for bug 24000 @@ -459,7 +495,7 @@ CSS_PROP_SVG(stroke-width, stroke_width, StrokeWidth, SVG, mStrokeWidth, eCSSTyp // the style structs but not in the nsCSS* structs should define // |CSS_PROP_INCLUDE_NOT_CSS|. (Some of these are also in nsRuleData*, // and a distinction might be needed at some point.) -// The first 4 parameters don't matter, but some compilers don't like +// The first 3 parameters don't matter, but some compilers don't like // empty arguments to macros. #ifdef CSS_PROP_INCLUDE_NOT_CSS CSS_PROP_VISIBILITY(X, X, X, Display, mLang, eCSSType_Value, PR_FALSE) diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 695c6053c7f2..53f25996221e 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -266,6 +266,20 @@ const PRInt32 nsCSSProps::kBackgroundRepeatKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBackgroundXPositionKTable[] = { + eCSSKeyword_left, 0, + eCSSKeyword_center, 50, + eCSSKeyword_right, 100, + -1,-1 +}; + +const PRInt32 nsCSSProps::kBackgroundYPositionKTable[] = { + eCSSKeyword_top, 0, + eCSSKeyword_center, 50, + eCSSKeyword_bottom, 100, + -1,-1 +}; + const PRInt32 nsCSSProps::kBorderCollapseKTable[] = { eCSSKeyword_collapse, NS_STYLE_BORDER_COLLAPSE, eCSSKeyword_separate, NS_STYLE_BORDER_SEPARATE, @@ -301,6 +315,12 @@ const PRInt32 nsCSSProps::kBorderWidthKTable[] = { -1,-1 }; +const PRInt32 nsCSSProps::kBoxPropSourceKTable[] = { + eCSSKeyword_physical, NS_BOXPROP_SOURCE_PHYSICAL, + eCSSKeyword_logical, NS_BOXPROP_SOURCE_LOGICAL, + -1,-1 +}; + const PRInt32 nsCSSProps::kBoxSizingKTable[] = { eCSSKeyword_content_box, NS_STYLE_BOX_SIZING_CONTENT, eCSSKeyword_border_box, NS_STYLE_BOX_SIZING_BORDER, @@ -917,25 +937,10 @@ nsCSSProps::SearchKeywordTable(PRInt32 aValue, const PRInt32 aTable[]) } // XXX TODO These table names should be additional parameters of the -// properties below in nsCSSPropList.h (and the two below should be like -// the rest). +// properties below in nsCSSPropList.h. const nsAFlatCString& nsCSSProps::LookupPropertyValue(nsCSSProperty aProp, PRInt32 aValue) { -static const PRInt32 kBackgroundXPositionKTable[] = { - eCSSKeyword_left, 0, - eCSSKeyword_center, 50, - eCSSKeyword_right, 100, - -1,-1 -}; - -static const PRInt32 kBackgroundYPositionKTable[] = { - eCSSKeyword_top, 0, - eCSSKeyword_center, 50, - eCSSKeyword_bottom, 100, - -1,-1 -}; - switch (aProp) { case eCSSProperty__moz_border_radius: @@ -1157,12 +1162,24 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty_margin: case eCSSProperty_margin_bottom: + case eCSSProperty_margin_end: + case eCSSProperty_margin_end_value: case eCSSProperty_margin_left: + case eCSSProperty_margin_left_value: case eCSSProperty_margin_right: + case eCSSProperty_margin_right_value: + case eCSSProperty_margin_start: + case eCSSProperty_margin_start_value: case eCSSProperty_margin_top: case eCSSProperty_marker_offset: break; + case eCSSProperty_margin_left_ltr_source: + case eCSSProperty_margin_left_rtl_source: + case eCSSProperty_margin_right_ltr_source: + case eCSSProperty_margin_right_rtl_source: + return SearchKeywordTable(aValue, kBoxPropSourceKTable); + case eCSSProperty_marks: return SearchKeywordTable(aValue, kPageMarksKTable); @@ -1191,12 +1208,24 @@ static const PRInt32 kBackgroundYPositionKTable[] = { case eCSSProperty_padding: case eCSSProperty_padding_bottom: + case eCSSProperty_padding_end: + case eCSSProperty_padding_end_value: case eCSSProperty_padding_left: + case eCSSProperty_padding_left_value: case eCSSProperty_padding_right: + case eCSSProperty_padding_right_value: + case eCSSProperty_padding_start: + case eCSSProperty_padding_start_value: case eCSSProperty_padding_top: case eCSSProperty_page: break; + case eCSSProperty_padding_left_ltr_source: + case eCSSProperty_padding_left_rtl_source: + case eCSSProperty_padding_right_ltr_source: + case eCSSProperty_padding_right_rtl_source: + return SearchKeywordTable(aValue, kBoxPropSourceKTable); + case eCSSProperty_page_break_before: case eCSSProperty_page_break_after: return SearchKeywordTable(aValue, kPageBreakKTable); @@ -1551,12 +1580,50 @@ static const nsCSSProperty gListStyleSubpropTable[] = { static const nsCSSProperty gMarginSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_margin_top, - eCSSProperty_margin_right, + eCSSProperty_margin_right_value, eCSSProperty_margin_bottom, - eCSSProperty_margin_left, + eCSSProperty_margin_left_value, + // extras: + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_right_rtl_source, eCSSProperty_UNKNOWN }; +static const nsCSSProperty gMarginLeftSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_left_value, + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMarginRightSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_right_value, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozMarginStartSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_start_value, + eCSSProperty_margin_left_ltr_source, + eCSSProperty_margin_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozMarginEndSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_margin_end_value, + eCSSProperty_margin_right_ltr_source, + eCSSProperty_margin_left_rtl_source, + eCSSProperty_UNKNOWN +}; + + static const nsCSSProperty gMozOutlineSubpropTable[] = { // nsCSSDeclaration.cpp outputs the subproperties in this order. eCSSProperty__moz_outline_color, @@ -1568,9 +1635,46 @@ static const nsCSSProperty gMozOutlineSubpropTable[] = { static const nsCSSProperty gPaddingSubpropTable[] = { // Code relies on these being in top-right-bottom-left order. eCSSProperty_padding_top, - eCSSProperty_padding_right, + eCSSProperty_padding_right_value, eCSSProperty_padding_bottom, - eCSSProperty_padding_left, + eCSSProperty_padding_left_value, + // extras: + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_left_rtl_source, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingLeftSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_left_value, + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_left_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gPaddingRightSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_right_value, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozPaddingStartSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_start_value, + eCSSProperty_padding_left_ltr_source, + eCSSProperty_padding_right_rtl_source, + eCSSProperty_UNKNOWN +}; + +static const nsCSSProperty gMozPaddingEndSubpropTable[] = { + // nsCSSParser::ParseDirectionalBoxProperty depends on this order + eCSSProperty_padding_end_value, + eCSSProperty_padding_right_ltr_source, + eCSSProperty_padding_left_rtl_source, eCSSProperty_UNKNOWN }; diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 3e79dede4a3b..4ece91eb3804 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -105,6 +105,8 @@ public: static const PRInt32 kBackgroundInlinePolicyKTable[]; static const PRInt32 kBackgroundOriginKTable[]; static const PRInt32 kBackgroundRepeatKTable[]; + static const PRInt32 kBackgroundXPositionKTable[]; + static const PRInt32 kBackgroundYPositionKTable[]; static const PRInt32 kBorderCollapseKTable[]; static const PRInt32 kBorderColorKTable[]; static const PRInt32 kBorderStyleKTable[]; @@ -118,6 +120,7 @@ public: static const PRInt32 kStrokeLinecapKTable[]; static const PRInt32 kStrokeLinejoinKTable[]; #endif + static const PRInt32 kBoxPropSourceKTable[]; static const PRInt32 kBoxSizingKTable[]; static const PRInt32 kCaptionSideKTable[]; static const PRInt32 kClearKTable[]; diff --git a/layout/style/nsCSSStruct.cpp b/layout/style/nsCSSStruct.cpp index b2ffbd191812..26f305040303 100644 --- a/layout/style/nsCSSStruct.cpp +++ b/layout/style/nsCSSStruct.cpp @@ -537,7 +537,19 @@ nsCSSMargin::nsCSSMargin(void) nsCSSMargin::nsCSSMargin(const nsCSSMargin& aCopy) : mMargin(aCopy.mMargin), + mMarginStart(aCopy.mMarginStart), + mMarginEnd(aCopy.mMarginEnd), + mMarginLeftLTRSource(aCopy.mMarginLeftLTRSource), + mMarginLeftRTLSource(aCopy.mMarginLeftRTLSource), + mMarginRightLTRSource(aCopy.mMarginRightLTRSource), + mMarginRightRTLSource(aCopy.mMarginRightRTLSource), mPadding(aCopy.mPadding), + mPaddingStart(aCopy.mPaddingStart), + mPaddingEnd(aCopy.mPaddingEnd), + mPaddingLeftLTRSource(aCopy.mPaddingLeftLTRSource), + mPaddingLeftRTLSource(aCopy.mPaddingLeftRTLSource), + mPaddingRightLTRSource(aCopy.mPaddingRightLTRSource), + mPaddingRightRTLSource(aCopy.mPaddingRightRTLSource), mBorderWidth(aCopy.mBorderWidth), mBorderColor(aCopy.mBorderColor), mBorderColors(aCopy.mBorderColors), diff --git a/layout/style/nsCSSStruct.h b/layout/style/nsCSSStruct.h index e2c0fc634a56..817c2cf15a69 100644 --- a/layout/style/nsCSSStruct.h +++ b/layout/style/nsCSSStruct.h @@ -245,7 +245,19 @@ struct nsCSSMargin : public nsCSSStruct { #endif nsCSSRect mMargin; + nsCSSValue mMarginStart; + nsCSSValue mMarginEnd; + nsCSSValue mMarginLeftLTRSource; + nsCSSValue mMarginLeftRTLSource; + nsCSSValue mMarginRightLTRSource; + nsCSSValue mMarginRightRTLSource; nsCSSRect mPadding; + nsCSSValue mPaddingStart; + nsCSSValue mPaddingEnd; + nsCSSValue mPaddingLeftLTRSource; + nsCSSValue mPaddingLeftRTLSource; + nsCSSValue mPaddingRightLTRSource; + nsCSSValue mPaddingRightRTLSource; nsCSSRect mBorderWidth; nsCSSRect mBorderColor; nsCSSValueListRect mBorderColors; diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index d475807bb8c5..f2c4a4be1476 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -1505,6 +1505,70 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex return nsnull; } +/* + * This function handles cascading of *-left or *-right box properties + * against *-start (which is L for LTR and R for RTL) or *-end (which is + * R for LTR and L for RTL). + * + * Cascading these properties correctly is hard because we need to + * cascade two properties as one, but which two properties depends on a + * third property ('direction'). We solve this by treating each of + * these properties (say, 'margin-start') as a shorthand that sets a + * property containing the value of the property specified + * ('margin-start-value') and sets a pair of properties + * ('margin-left-ltr-source' and 'margin-right-rtl-source') saying which + * of the properties we use. Thus, when we want to compute the value of + * 'margin-left' when 'direction' is 'ltr', we look at the value of + * 'margin-left-ltr-source', which tells us whether to use the highest + * 'margin-left' in the cascade or the highest 'margin-start'. + * + * Finally, since we can compute the normal (*-left and *-right) + * properties in a loop, this function works by assuming the computation + * for those properties has happened as though we have not implemented + * the logical properties (*-start and *-end). It is the responsibility + * of this function to replace the computed values with the values + * computed from the logical properties when needed. + */ +void +nsRuleNode::AdjustLogicalBoxProp(nsStyleContext* aContext, + const nsCSSValue& aLTRSource, + const nsCSSValue& aRTLSource, + const nsCSSValue& aLTRLogicalValue, + const nsCSSValue& aRTLLogicalValue, + const nsStyleSides& aParentRect, + nsStyleSides& aRect, + PRUint8 aSide, + PRInt32 aMask, + PRBool& aInherited) +{ + PRBool LTRlogical = aLTRSource.GetUnit() == eCSSUnit_Enumerated && + aLTRSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL; + PRBool RTLlogical = aRTLSource.GetUnit() == eCSSUnit_Enumerated && + aRTLSource.GetIntValue() == NS_BOXPROP_SOURCE_LOGICAL; + if (LTRlogical || RTLlogical) { + // We can't cache anything on the rule tree if we use any data from + // the style context, since data cached in the rule tree could be + // used with a style context with a different value. + aInherited = PR_TRUE; + PRUint8 dir = aContext->GetStyleVisibility()->mDirection; + + nsStyleCoord parentCoord; + nsStyleCoord coord; + aParentRect.Get(aSide, parentCoord); + if (dir == NS_STYLE_DIRECTION_LTR) { + if (LTRlogical && + SetCoord(aLTRLogicalValue, coord, parentCoord, aMask, aContext, + mPresContext, aInherited)) + aRect.Set(aSide, coord); + } else { + if (RTLlogical && + SetCoord(aRTLLogicalValue, coord, parentCoord, aMask, aContext, + mPresContext, aInherited)) + aRect.Set(aSide, coord); + } + } +} + /* static */ void nsRuleNode::SetFont(nsIPresContext* aPresContext, nsStyleContext* aContext, nscoord aMinFontSize, PRBool aUseDocumentFonts, @@ -3012,6 +3076,19 @@ nsRuleNode::ComputeMarginData(nsStyleStruct* aStartStruct, } } + AdjustLogicalBoxProp(aContext, + marginData.mMarginLeftLTRSource, + marginData.mMarginLeftRTLSource, + marginData.mMarginStart, marginData.mMarginEnd, + parentMargin->mMargin, margin->mMargin, + NS_SIDE_LEFT, SETCOORD_LPAH, inherited); + AdjustLogicalBoxProp(aContext, + marginData.mMarginRightLTRSource, + marginData.mMarginRightRTLSource, + marginData.mMarginEnd, marginData.mMarginStart, + parentMargin->mMargin, margin->mMargin, + NS_SIDE_RIGHT, SETCOORD_LPAH, inherited); + if (inherited) // We inherited, and therefore can't be cached in the rule node. We have to be put right on the // style context. @@ -3229,6 +3306,19 @@ nsRuleNode::ComputePaddingData(nsStyleStruct* aStartStruct, } } + AdjustLogicalBoxProp(aContext, + marginData.mPaddingLeftLTRSource, + marginData.mPaddingLeftRTLSource, + marginData.mPaddingStart, marginData.mPaddingEnd, + parentPadding->mPadding, padding->mPadding, + NS_SIDE_LEFT, SETCOORD_LPH, inherited); + AdjustLogicalBoxProp(aContext, + marginData.mPaddingRightLTRSource, + marginData.mPaddingRightRTLSource, + marginData.mPaddingEnd, marginData.mPaddingStart, + parentPadding->mPadding, padding->mPadding, + NS_SIDE_RIGHT, SETCOORD_LPH, inherited); + if (inherited) // We inherited, and therefore can't be cached in the rule node. We have to be put right on the // style context. diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index 22fdfd7ab19c..59ece654ccb9 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -497,6 +497,17 @@ protected: const nsRuleDataFont& aFontData, PRUint8 aGenericFontID, nscoord aMinFontSize, PRBool aUseDocumentFonts, nsStyleFont* aFont); + + void AdjustLogicalBoxProp(nsStyleContext* aContext, + const nsCSSValue& aLTRSource, + const nsCSSValue& aRTLSource, + const nsCSSValue& aLTRLogicalValue, + const nsCSSValue& aRTLLogicalValue, + const nsStyleSides& aParentRect, + nsStyleSides& aRect, + PRUint8 aSide, + PRInt32 aMask, + PRBool& aInherited); inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID, const nsRuleDataStruct& aRuleDataStruct);