diff --git a/layout/reftests/bugs/608756-1-ref.html b/layout/reftests/bugs/608756-1-ref.html
new file mode 100644
index 00000000000..d62c43d9edc
--- /dev/null
+++ b/layout/reftests/bugs/608756-1-ref.html
@@ -0,0 +1,4 @@
+
+
+Test
Test
+
diff --git a/layout/reftests/bugs/608756-1a.html b/layout/reftests/bugs/608756-1a.html
new file mode 100644
index 00000000000..aacca22b926
--- /dev/null
+++ b/layout/reftests/bugs/608756-1a.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+Test
Test
+
diff --git a/layout/reftests/bugs/608756-1b.html b/layout/reftests/bugs/608756-1b.html
new file mode 100644
index 00000000000..98ffe0a8092
--- /dev/null
+++ b/layout/reftests/bugs/608756-1b.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+Test
Test
+
diff --git a/layout/reftests/bugs/608756-2-ref.html b/layout/reftests/bugs/608756-2-ref.html
new file mode 100644
index 00000000000..c68452f5221
--- /dev/null
+++ b/layout/reftests/bugs/608756-2-ref.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+Test
Test
+
diff --git a/layout/reftests/bugs/608756-2.html b/layout/reftests/bugs/608756-2.html
new file mode 100644
index 00000000000..558462b9d89
--- /dev/null
+++ b/layout/reftests/bugs/608756-2.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+Test
Test
+
diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list
index 462e9a12cfe..9f92c3f2e42 100644
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1599,6 +1599,9 @@ fails-if(!haveTestPlugin) == 599476.html 599476-ref.html
== 604737.html 604737-ref.html
== 605138-1.html 605138-1-ref.html
== 605157-1.xhtml 605157-1-ref.xhtml
+== 608756-1a.html 608756-1-ref.html
+== 608756-1b.html 608756-1-ref.html
+== 608756-2.html 608756-2-ref.html
== 609272-1.html 609272-1-ref.html
== 608636-1.html 608636-1-ref.html
needs-focus == 613433-1.html 613433-1-ref.html
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 6f2d45ebf21..27336bf8ea5 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3875,6 +3875,14 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
{
COMPUTE_START_RESET(Display, (), display, parentDisplay)
+ // We may have ended up with aStartStruct's values of mDisplay and
+ // mFloats, but those may not be correct if our style data overrides
+ // its position or float properties. Reset to mOriginalDisplay and
+ // mOriginalFloats; it if turns out we still need the display/floats
+ // adjustments we'll do them below.
+ display->mDisplay = display->mOriginalDisplay;
+ display->mFloats = display->mOriginalFloats;
+
// Each property's index in this array must match its index in the
// const array |transitionPropInfo| above.
TransitionPropData transitionPropData[4];
@@ -4281,6 +4289,10 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
SetDiscrete(*aRuleData->ValueForDisplay(), display->mDisplay, canStoreInRuleTree,
SETDSC_ENUMERATED, parentDisplay->mDisplay,
NS_STYLE_DISPLAY_INLINE, 0, 0, 0, 0);
+ // Backup original display value for calculation of a hypothetical
+ // box (CSS2 10.6.4/10.6.5), in addition to getting our style data right later.
+ // See nsHTMLReflowState::CalculateHypotheticalBox
+ display->mOriginalDisplay = display->mDisplay;
// appearance: enum, inherit, initial
SetDiscrete(*aRuleData->ValueForAppearance(),
@@ -4358,6 +4370,8 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
display->mFloats, canStoreInRuleTree,
SETDSC_ENUMERATED, parentDisplay->mFloats,
NS_STYLE_FLOAT_NONE, 0, 0, 0, 0);
+ // Save mFloats in mOriginalFloats in case we need it later
+ display->mOriginalFloats = display->mFloats;
// overflow-x: enum, inherit, initial
SetDiscrete(*aRuleData->ValueForOverflowX(),
@@ -4483,7 +4497,8 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
if (nsCSSPseudoElements::firstLetter == aContext->GetPseudo()) {
// a non-floating first-letter must be inline
// XXX this fix can go away once bug 103189 is fixed correctly
- display->mDisplay = NS_STYLE_DISPLAY_INLINE;
+ // Note that we reset mOriginalDisplay to enforce the invariant that it equals mDisplay if we're not positioned or floating.
+ display->mOriginalDisplay = display->mDisplay = NS_STYLE_DISPLAY_INLINE;
// We can't cache the data in the rule tree since if a more specific
// rule has 'float: left' we'll end up with the wrong 'display'
@@ -4494,28 +4509,25 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
if (display->IsAbsolutelyPositioned()) {
// 1) if position is 'absolute' or 'fixed' then display must be
// block-level and float must be 'none'
-
- // Backup original display value for calculation of a hypothetical
- // box (CSS2 10.6.4/10.6.5).
- // See nsHTMLReflowState::CalculateHypotheticalBox
- display->mOriginalDisplay = display->mDisplay;
EnsureBlockDisplay(display->mDisplay);
display->mFloats = NS_STYLE_FLOAT_NONE;
- // We can't cache the data in the rule tree since if a more specific
- // rule has 'position: static' we'll end up with problems with the
- // 'display' and 'float' properties.
- canStoreInRuleTree = false;
+ // Note that it's OK to cache this struct in the ruletree
+ // because it's fine as-is for any style context that points to
+ // it directly, and any use of it as aStartStruct (e.g. if a
+ // more specific rule sets "position: static") will use
+ // mOriginalDisplay and mOriginalFloats, which we have carefully
+ // not changed.
} else if (display->mFloats != NS_STYLE_FLOAT_NONE) {
// 2) if float is not none, and display is not none, then we must
// set a block-level 'display' type per CSS2.1 section 9.7.
-
EnsureBlockDisplay(display->mDisplay);
- // We can't cache the data in the rule tree since if a more specific
- // rule has 'float: none' we'll end up with the wrong 'display'
- // property.
- canStoreInRuleTree = false;
+ // Note that it's OK to cache this struct in the ruletree
+ // because it's fine as-is for any style context that points to
+ // it directly, and any use of it as aStartStruct (e.g. if a
+ // more specific rule sets "float: none") will use
+ // mOriginalDisplay, which we have carefully not changed.
}
}
diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp
index 80ae1927e9a..1cb86e6213e 100644
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -374,10 +374,17 @@ nsStyleContext::ApplyStyleFixups(nsPresContext* aPresContext)
disp->mDisplay != NS_STYLE_DISPLAY_TABLE) {
nsStyleDisplay *mutable_display = static_cast
(GetUniqueStyleData(eStyleStruct_Display));
+ // If we're in this code, then mOriginalDisplay doesn't matter
+ // for purposes of the cascade (because this nsStyleDisplay
+ // isn't living in the ruletree anyway), and for determining
+ // hypothetical boxes it's better to have mOriginalDisplay
+ // matching mDisplay here.
if (mutable_display->mDisplay == NS_STYLE_DISPLAY_INLINE_TABLE)
- mutable_display->mDisplay = NS_STYLE_DISPLAY_TABLE;
+ mutable_display->mOriginalDisplay = mutable_display->mDisplay =
+ NS_STYLE_DISPLAY_TABLE;
else
- mutable_display->mDisplay = NS_STYLE_DISPLAY_BLOCK;
+ mutable_display->mOriginalDisplay = mutable_display->mDisplay =
+ NS_STYLE_DISPLAY_BLOCK;
}
}
diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp
index 20d3b23ec08..988070a0bd2 100644
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2080,9 +2080,10 @@ nsStyleDisplay::nsStyleDisplay()
MOZ_COUNT_CTOR(nsStyleDisplay);
mAppearance = NS_THEME_NONE;
mDisplay = NS_STYLE_DISPLAY_INLINE;
- mOriginalDisplay = NS_STYLE_DISPLAY_NONE;
+ mOriginalDisplay = mDisplay;
mPosition = NS_STYLE_POSITION_STATIC;
mFloats = NS_STYLE_FLOAT_NONE;
+ mOriginalFloats = mFloats;
mBreakType = NS_STYLE_CLEAR_NONE;
mBreakBefore = false;
mBreakAfter = false;
@@ -2146,6 +2147,7 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
mAppearance = aSource.mAppearance;
mDisplay = aSource.mDisplay;
mOriginalDisplay = aSource.mOriginalDisplay;
+ mOriginalFloats = aSource.mOriginalFloats;
mBinding = aSource.mBinding;
mPosition = aSource.mPosition;
mFloats = aSource.mFloats;
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index db96bc65811..332b089d570 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1539,9 +1539,13 @@ struct nsStyleDisplay {
float mOpacity; // [reset]
PRUint8 mDisplay; // [reset] see nsStyleConsts.h NS_STYLE_DISPLAY_*
PRUint8 mOriginalDisplay; // [reset] saved mDisplay for position:absolute/fixed
+ // and float:left/right; otherwise equal
+ // to mDisplay
PRUint8 mAppearance; // [reset]
PRUint8 mPosition; // [reset] see nsStyleConsts.h
PRUint8 mFloats; // [reset] see nsStyleConsts.h NS_STYLE_FLOAT_*
+ PRUint8 mOriginalFloats; // [reset] saved mFloats for position:absolute/fixed;
+ // otherwise equal to mFloats
PRUint8 mBreakType; // [reset] see nsStyleConsts.h NS_STYLE_CLEAR_*
bool mBreakBefore; // [reset]
bool mBreakAfter; // [reset]