From 0b3d9b76ccab61ce22ad32babb32d63f730b008a Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 4 Jun 2008 23:46:24 -0700 Subject: [PATCH] b=346189, children should optionally not affect size of XUL stack; r+sr=roc --- content/base/src/nsGkAtomList.h | 2 + dom/public/idl/css/nsIDOMCSS2Properties.idl | 4 +- layout/base/nsStyleConsts.h | 4 + layout/reftests/bugs/346189-1-ref.xul | 56 ++++++++++++++ layout/reftests/bugs/346189-1.xul | 71 ++++++++++++++++++ layout/reftests/bugs/reftest.list | 1 + layout/style/nsCSSKeywordList.h | 1 + layout/style/nsCSSParser.cpp | 3 + layout/style/nsCSSPropList.h | 1 + layout/style/nsCSSProps.cpp | 6 ++ layout/style/nsCSSProps.h | 1 + layout/style/nsCSSStruct.h | 1 + layout/style/nsComputedDOMStyle.cpp | 13 ++++ layout/style/nsComputedDOMStyle.h | 1 + layout/style/nsRuleNode.cpp | 10 +++ layout/style/nsStyleStruct.cpp | 1 + layout/style/nsStyleStruct.h | 1 + layout/style/test/property_database.js | 8 ++ layout/xul/base/src/nsStackLayout.cpp | 83 ++++++++++++--------- 19 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 layout/reftests/bugs/346189-1-ref.xul create mode 100644 layout/reftests/bugs/346189-1.xul diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index b68ffab5b37..5b7d80a8934 100755 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -397,6 +397,7 @@ GK_ATOM(i, "i") GK_ATOM(id, "id") GK_ATOM(_if, "if") GK_ATOM(iframe, "iframe") +GK_ATOM(ignore, "ignore") GK_ATOM(ignorecase, "ignorecase") GK_ATOM(ignorekeys, "ignorekeys") GK_ATOM(ilayer, "ilayer") @@ -802,6 +803,7 @@ GK_ATOM(staticHint, "staticHint") GK_ATOM(statustext, "statustext") GK_ATOM(stop, "stop") GK_ATOM(stretch, "stretch") +GK_ATOM(stretch_to_fit, "stretch-to-fit") GK_ATOM(strike, "strike") GK_ATOM(string, "string") GK_ATOM(stringLength, "string-length") diff --git a/dom/public/idl/css/nsIDOMCSS2Properties.idl b/dom/public/idl/css/nsIDOMCSS2Properties.idl index 88a99e67986..908318278ca 100644 --- a/dom/public/idl/css/nsIDOMCSS2Properties.idl +++ b/dom/public/idl/css/nsIDOMCSS2Properties.idl @@ -406,7 +406,7 @@ interface nsIDOMCSS2Properties : nsISupports // raises(DOMException) on setting }; -[scriptable, uuid(c9339b8c-9bdd-4d2a-a61a-55ca609b92bd)] +[scriptable, uuid(8a5b178d-c805-4f8e-8992-fa7c5c11d08e)] interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties { /* Non-DOM 2 extensions */ @@ -591,4 +591,6 @@ interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties attribute DOMString MozBorderStartWidth; // raises(DOMException) on setting + attribute DOMString MozStackSizing; + // raises(DOMException) on setting }; diff --git a/layout/base/nsStyleConsts.h b/layout/base/nsStyleConsts.h index dd94093a7d1..24bfc04bb6e 100644 --- a/layout/base/nsStyleConsts.h +++ b/layout/base/nsStyleConsts.h @@ -128,6 +128,10 @@ #define NS_STYLE_BOX_ORIENT_HORIZONTAL 0 #define NS_STYLE_BOX_ORIENT_VERTICAL 1 +// stack-sizing +#define NS_STYLE_STACK_SIZING_IGNORE 0 +#define NS_STYLE_STACK_SIZING_STRETCH_TO_FIT 1 + // Azimuth - See nsStyleAural #define NS_STYLE_AZIMUTH_LEFT_SIDE 0x00 #define NS_STYLE_AZIMUTH_FAR_LEFT 0x01 diff --git a/layout/reftests/bugs/346189-1-ref.xul b/layout/reftests/bugs/346189-1-ref.xul new file mode 100644 index 00000000000..e4839b3790c --- /dev/null +++ b/layout/reftests/bugs/346189-1-ref.xul @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/bugs/346189-1.xul b/layout/reftests/bugs/346189-1.xul new file mode 100644 index 00000000000..59ff2334384 --- /dev/null +++ b/layout/reftests/bugs/346189-1.xul @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index a45f36286ff..94dfe27b7c8 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -301,6 +301,7 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 333970-1.html 333970-1-ref.html # bug 3 == 345267-1c.html 345267-1-ref.html == 345267-1d.html 345267-1-ref.html != 345563-sub.xhtml 345563-sup.xhtml +== 346189-1.xul 346189-1-ref.xul == 346774-1a.html 346774-1-ref.html == 346774-1b.html 346774-1-ref.html == 346774-1c.html 346774-1-ref.html diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index e966623e5c3..7870cdffd24 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -418,6 +418,7 @@ CSS_KEY(start, start) CSS_KEY(static, static) CSS_KEY(status-bar, status_bar) CSS_KEY(stretch, stretch) +CSS_KEY(stretch-to-fit, stretch_to_fit) CSS_KEY(sub, sub) CSS_KEY(super, super) CSS_KEY(sw-resize, sw_resize) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index c3150f2430e..fb844c63921 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -5070,6 +5070,9 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode, case eCSSProperty_speech_rate: return ParseVariant(aErrorCode, aValue, VARIANT_HN | VARIANT_KEYWORD, nsCSSProps::kSpeechRateKTable); + case eCSSProperty_stack_sizing: + return ParseVariant(aErrorCode, aValue, VARIANT_HK, + nsCSSProps::kStackSizingKTable); case eCSSProperty_stress: return ParseVariant(aErrorCode, aValue, VARIANT_HN, nsnull); case eCSSProperty_table_layout: diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h index 6967f9d889c..839b40830b1 100644 --- a/layout/style/nsCSSPropList.h +++ b/layout/style/nsCSSPropList.h @@ -516,6 +516,7 @@ CSS_PROP_XUL(-moz-box-flex, box_flex, MozBoxFlex, XUL, mBoxFlex, eCSSType_Value, CSS_PROP_XUL(-moz-box-orient, box_orient, MozBoxOrient, XUL, mBoxOrient, eCSSType_Value, kBoxOrientKTable) // XXX bug 3935 CSS_PROP_XUL(-moz-box-pack, box_pack, MozBoxPack, XUL, mBoxPack, eCSSType_Value, kBoxPackKTable) // XXX bug 3935 CSS_PROP_XUL(-moz-box-ordinal-group, box_ordinal_group, MozBoxOrdinalGroup, XUL, mBoxOrdinal, eCSSType_Value, nsnull) +CSS_PROP_XUL(-moz-stack-sizing, stack_sizing, MozStackSizing, XUL, mStackSizing, eCSSType_Value, kStackSizingKTable) #ifdef MOZ_MATHML #ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index 8a9845a7625..2c38d2819e1 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -860,6 +860,12 @@ const PRInt32 nsCSSProps::kSpeechRateKTable[] = { eCSSKeyword_UNKNOWN,-1 }; +const PRInt32 nsCSSProps::kStackSizingKTable[] = { + eCSSKeyword_ignore, NS_STYLE_STACK_SIZING_IGNORE, + eCSSKeyword_stretch_to_fit, NS_STYLE_STACK_SIZING_STRETCH_TO_FIT, + eCSSKeyword_UNKNOWN,-1 +}; + const PRInt32 nsCSSProps::kTableLayoutKTable[] = { eCSSKeyword_fixed, NS_STYLE_TABLE_LAYOUT_FIXED, eCSSKeyword_UNKNOWN,-1 diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index b306593c7bd..3f2da407bed 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -177,6 +177,7 @@ public: static const PRInt32 kSpeakNumeralKTable[]; static const PRInt32 kSpeakPunctuationKTable[]; static const PRInt32 kSpeechRateKTable[]; + static const PRInt32 kStackSizingKTable[]; static const PRInt32 kTableLayoutKTable[]; static const PRInt32 kTextAlignKTable[]; static const PRInt32 kTextDecorationKTable[]; diff --git a/layout/style/nsCSSStruct.h b/layout/style/nsCSSStruct.h index 39f16a7842b..392a8f23520 100644 --- a/layout/style/nsCSSStruct.h +++ b/layout/style/nsCSSStruct.h @@ -548,6 +548,7 @@ struct nsCSSXUL : public nsCSSStruct { nsCSSValue mBoxOrient; nsCSSValue mBoxPack; nsCSSValue mBoxOrdinal; + nsCSSValue mStackSizing; private: nsCSSXUL(const nsCSSXUL& aOther); // NOT IMPLEMENTED }; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index aec5be0f8bb..04c6736ed9a 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -486,6 +486,18 @@ nsComputedDOMStyle::GetBottom(nsIDOMCSSValue** aValue) return GetOffsetWidthFor(NS_SIDE_BOTTOM, aValue); } +nsresult +nsComputedDOMStyle::GetStackSizing(nsIDOMCSSValue** aValue) +{ + nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue(); + NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY); + + val->SetIdent(GetStyleXUL()->mStretchStack ? nsGkAtoms::stretch_to_fit : + nsGkAtoms::ignore); + + return CallQueryInterface(val, aValue); +} + nsresult nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor) @@ -3806,6 +3818,7 @@ nsComputedDOMStyle::GetQueryablePropertyMap(PRUint32* aLength) COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_bottomRight,OutlineRadiusBottomRight), COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topLeft, OutlineRadiusTopLeft), COMPUTED_STYLE_MAP_ENTRY(_moz_outline_radius_topRight, OutlineRadiusTopRight), + COMPUTED_STYLE_MAP_ENTRY(stack_sizing, StackSizing), COMPUTED_STYLE_MAP_ENTRY(user_focus, UserFocus), COMPUTED_STYLE_MAP_ENTRY(user_input, UserInput), COMPUTED_STYLE_MAP_ENTRY(user_modify, UserModify), diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 813ec3b71e7..bda981465fd 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -133,6 +133,7 @@ private: nsresult GetTop(nsIDOMCSSValue** aValue); nsresult GetRight(nsIDOMCSSValue** aValue); nsresult GetBottom(nsIDOMCSSValue** aValue); + nsresult GetStackSizing(nsIDOMCSSValue** aValue); /* Font properties */ nsresult GetColor(nsIDOMCSSValue** aValue); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 7bb4df6e877..d00d4ceef63 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -4525,6 +4525,16 @@ nsRuleNode::ComputeXULData(void* aStartStruct, xul->mBoxOrdinal = 1; } + if (eCSSUnit_Inherit == xulData.mStackSizing.GetUnit()) { + inherited = PR_TRUE; + xul->mStretchStack = parentXUL->mStretchStack; + } else if (eCSSUnit_Initial == xulData.mStackSizing.GetUnit()) { + xul->mStretchStack = PR_TRUE; + } else if (eCSSUnit_Enumerated == xulData.mStackSizing.GetUnit()) { + xul->mStretchStack = xulData.mStackSizing.GetIntValue() == + NS_STYLE_STACK_SIZING_STRETCH_TO_FIT; + } + COMPUTE_END_RESET(XUL, xul) } diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 56facf68de2..e5167e45bc8 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -573,6 +573,7 @@ nsStyleXUL::nsStyleXUL() mBoxOrient = NS_STYLE_BOX_ORIENT_HORIZONTAL; mBoxPack = NS_STYLE_BOX_PACK_START; mBoxOrdinal = 1; + mStretchStack = PR_TRUE; } nsStyleXUL::~nsStyleXUL() diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index a55f3a9ce59..c8c21201406 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1187,6 +1187,7 @@ struct nsStyleXUL { PRUint8 mBoxDirection; // [reset] see nsStyleConsts.h PRUint8 mBoxOrient; // [reset] see nsStyleConsts.h PRUint8 mBoxPack; // [reset] see nsStyleConsts.h + PRPackedBool mStretchStack; // [reset] see nsStyleConsts.h }; struct nsStyleColumn { diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index b90672d50eb..7ae584d691b 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -442,6 +442,14 @@ var gCSSProperties = { other_values: [ "1px", "3em" ], invalid_values: [] }, + "-moz-stack-sizing": { + domProp: "MozStackSizing", + inherited: false, + type: CSS_TYPE_LONGHAND, + initial_values: [ "stretch-to-fit" ], + other_values: [ "ignore" ], + invalid_values: [] + }, "-moz-user-focus": { domProp: "MozUserFocus", inherited: true, diff --git a/layout/xul/base/src/nsStackLayout.cpp b/layout/xul/base/src/nsStackLayout.cpp index 8cbc2c9483d..d5fa95d3fba 100644 --- a/layout/xul/base/src/nsStackLayout.cpp +++ b/layout/xul/base/src/nsStackLayout.cpp @@ -76,29 +76,35 @@ nsStackLayout::nsStackLayout() { } +/* + * Sizing: we are as wide as the widest child plus its left offset + * we are tall as the tallest child plus its top offset. + * + * Only children which have -moz-stack-sizing set to stretch-to-fit + * (the default) will be included in the size computations. + */ + nsSize nsStackLayout::GetPrefSize(nsIBox* aBox, nsBoxLayoutState& aState) { - nsSize rpref (0, 0); - - // we are as wide as the widest child plus its left offset - // we are tall as the tallest child plus its top offset + nsSize prefSize (0, 0); nsIBox* child = aBox->GetChildBox(); - while (child) { - nsSize pref = child->GetPrefSize(aState); + while (child) { + if (child->GetStyleXUL()->mStretchStack) { + nsSize pref = child->GetPrefSize(aState); - AddMargin(child, pref); - AddOffset(aState, child, pref); - AddLargestSize(rpref, pref); + AddMargin(child, pref); + AddOffset(aState, child, pref); + AddLargestSize(prefSize, pref); + } child = child->GetNextBox(); } - // now add our border and padding - AddBorderAndPadding(aBox, rpref); + AddBorderAndPadding(aBox, prefSize); - return rpref; + return prefSize; } nsSize @@ -106,19 +112,19 @@ nsStackLayout::GetMinSize(nsIBox* aBox, nsBoxLayoutState& aState) { nsSize minSize (0, 0); - // run through all the children and get their min, max, and preferred sizes - nsIBox* child = aBox->GetChildBox(); - while (child) { - nsSize min = child->GetMinSize(aState); - AddMargin(child, min); - AddOffset(aState, child, min); - AddLargestSize(minSize, min); + while (child) { + if (child->GetStyleXUL()->mStretchStack) { + nsSize min = child->GetMinSize(aState); + + AddMargin(child, min); + AddOffset(aState, child, min); + AddLargestSize(minSize, min); + } child = child->GetNextBox(); } - // now add our border and padding AddBorderAndPadding(aBox, minSize); return minSize; @@ -129,21 +135,22 @@ nsStackLayout::GetMaxSize(nsIBox* aBox, nsBoxLayoutState& aState) { nsSize maxSize (NS_INTRINSICSIZE, NS_INTRINSICSIZE); - // run through all the children and get their min, max, and preferred sizes - nsIBox* child = aBox->GetChildBox(); - while (child) { - nsSize min = child->GetMinSize(aState); - nsSize max = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState)); + while (child) { + if (child->GetStyleXUL()->mStretchStack) { + nsSize min = child->GetMinSize(aState); + nsSize max = child->GetMaxSize(aState); - AddMargin(child, max); - AddOffset(aState, child, max); - AddSmallestSize(maxSize, max); + max = nsBox::BoundsCheckMinMax(min, max); + + AddMargin(child, max); + AddOffset(aState, child, max); + AddSmallestSize(maxSize, max); + } child = child->GetNextBox(); } - // now add our border and padding AddBorderAndPadding(aBox, maxSize); return maxSize; @@ -292,15 +299,17 @@ nsStackLayout::Layout(nsIBox* aBox, nsBoxLayoutState& aState) childRectNoMargin = childRect = child->GetRect(); childRect.Inflate(margin); - // Did the child push back on us and get bigger? - if (offset.width + childRect.width > clientRect.width) { - clientRect.width = childRect.width + offset.width; - grow = PR_TRUE; - } + if (child->GetStyleXUL()->mStretchStack) { + // Did the child push back on us and get bigger? + if (offset.width + childRect.width > clientRect.width) { + clientRect.width = childRect.width + offset.width; + grow = PR_TRUE; + } - if (offset.height + childRect.height > clientRect.height) { - clientRect.height = childRect.height + offset.height; - grow = PR_TRUE; + if (offset.height + childRect.height > clientRect.height) { + clientRect.height = childRect.height + offset.height; + grow = PR_TRUE; + } } if (childRectNoMargin != oldRect)