Bug 1263845. When a parent changes from auto height to non-auto height or vice versa, a percentage height non-block child needs to realize it's doing a vertical resize. r=dbaron
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 26 Apr 2016 12:56:26 -0400
changeset 294952 4e08f29820a35936be6142b86350318e3246633d
parent 294951 6dd235136facc833619c153a6f27bfe96f709cb7
child 294953 24fd925eb06d5af6d3219ade2541aac75902976a
push id75741
push userbzbarsky@mozilla.com
push dateTue, 26 Apr 2016 16:56:57 +0000
treeherdermozilla-inbound@4e08f29820a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1263845
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1263845. When a parent changes from auto height to non-auto height or vice versa, a percentage height non-block child needs to realize it's doing a vertical resize. r=dbaron
layout/generic/nsHTMLReflowState.cpp
layout/reftests/bugs/1263845-ref.html
layout/reftests/bugs/1263845.html
layout/reftests/bugs/reftest.list
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -633,16 +633,39 @@ nsHTMLReflowState::InitResizeFlags(nsPre
     // reflowing descendant.
     SetBResize(true);
   } else if (mCBReflowState && frame->IsBlockWrapper()) {
     // XXX Is this problematic for relatively positioned inlines acting
     // as containing block for absolutely positioned elements?
     // Possibly; in that case we should at least be checking
     // NS_SUBTREE_DIRTY, I'd think.
     SetBResize(mCBReflowState->IsBResize());
+  } else if (mCBReflowState && !nsLayoutUtils::GetAsBlock(frame)) {
+    // Some non-block frames (e.g. table frames) aggressively optimize out their
+    // BSize recomputation when they don't have the BResize flag set.  This
+    // means that if they go from having a computed non-auto height to having an
+    // auto height and don't have that flag set, they will not actually compute
+    // their auto height and will just remain at whatever size they already
+    // were.  We can end up in that situation if the child has a percentage
+    // specified height and the parent changes from non-auto height to auto
+    // height.  When that happens, the parent will typically have the BResize
+    // flag set, and we want to propagate that flag to the kid.
+    //
+    // Ideally it seems like we'd do this for blocks too, of course... but we'd
+    // really want to restrict it to the percentage height case or something, to
+    // avoid extra reflows in common cases.  Maybe we should be examining
+    // mStylePosition->BSize(wm).GetUnit() for that purpose?
+    //
+    // Note that we _also_ need to set the BResize flag if we have auto
+    // ComputedBSize() and a dirty subtree, since that might require us to
+    // change BSize due to kids having been added or removed.
+    SetBResize(mCBReflowState->IsBResize());
+    if (ComputedBSize() == NS_AUTOHEIGHT) {
+      SetBResize(IsBResize() || NS_SUBTREE_DIRTY(frame));
+    }
   } else if (ComputedBSize() == NS_AUTOHEIGHT) {
     if (eCompatibility_NavQuirks == aPresContext->CompatibilityMode() &&
         mCBReflowState) {
       SetBResize(mCBReflowState->IsBResize());
     } else {
       SetBResize(IsIResize());
     }
     SetBResize(IsBResize() || NS_SUBTREE_DIRTY(frame));
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1263845-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<div id="wrap" style="background: yellow">
+  <table style="height: 100%; background: purple">
+    <tr>
+      <td>
+        This is some text
+      </td>
+    </tr>
+  </table>
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1263845.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<div id="wrap" style="height: 200px; background: yellow">
+  <table style="height: 100%; background: purple">
+    <tr>
+      <td>
+        This is some text
+      </td>
+    </tr>
+  </table>
+</div>
+<script>
+  // Make sure we do a layout at the 200px height.
+  document.body.offsetWidth;
+  document.getElementById("wrap").style.height = "";
+</script>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1944,9 +1944,10 @@ fuzzy(1,74) fuzzy-if(gtkWidget,6,79) == 
 == 1222226-1.html 1222226-1-ref.html
 pref(layout.css.overflow-clip-box.enabled,true) == 1226278.html 1226278-ref.html
 == 1230466.html about:blank
 random-if(gtkWidget) != 1238243-1.html 1238243-1-notref.html # may fail on Linux, depending on Korean fonts available
 random-if(OSX==1006) == 1238243-2.html 1238243-2-ref.html # fails on 10.6 with default fonts because filler has a visible glyph
 fuzzy(100,2000) == 1239564.html 1239564-ref.html
 == 1242172-1.html 1242172-1-ref.html
 == 1242172-2.html 1242172-2-ref.html
+== 1263845.html 1263845-ref.html
 == 1260543-1.html 1260543-1-ref.html