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)