Bug 1505817 - Handle the case where a float is dynamically inserted inside a continuation. r=dbaron, a=jcristau
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 08 Nov 2018 21:37:16 +0000
changeset 501218 5b355cd76cea5b71bd2affd16bcf6f258a5125eb
parent 501217 23d0264564e5dd6a1ed4f9cce45188f7c60d28c2
child 501219 0ab056dc26a8334daba227f5c9b2bb67f99e51c1
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron, jcristau
bugs1505817
milestone64.0
Bug 1505817 - Handle the case where a float is dynamically inserted inside a continuation. r=dbaron, a=jcristau The first assertion that fails here, and which causes all the havoc later, is: https://dev.searchfox.org/mozilla-central/rev/6e0e603f4852b8e571e5b8ae133e772b18b6016e/layout/generic/BlockReflowInput.cpp#578 That happens because the float has been dynamically inserted directly under one of the continuations of the column set, not under the first. So that assertion doesn't really hold. Properly steal the float if that happens. Differential Revision: https://phabricator.services.mozilla.com/D11359
layout/generic/BlockReflowInput.cpp
layout/generic/crashtests/1505817.html
layout/generic/crashtests/crashtests.list
--- a/layout/generic/BlockReflowInput.cpp
+++ b/layout/generic/BlockReflowInput.cpp
@@ -570,31 +570,31 @@ BlockReflowInput::AddFloat(nsLineLayout*
   MOZ_ASSERT(aLineLayout, "must have line layout");
   MOZ_ASSERT(mBlock->LinesEnd() != mCurrentLine, "null ptr");
   MOZ_ASSERT(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
              "aFloat must be an out-of-flow frame");
 
   MOZ_ASSERT(aFloat->GetParent(), "float must have parent");
   MOZ_ASSERT(aFloat->GetParent()->IsFrameOfType(nsIFrame::eBlockFrame),
              "float's parent must be block");
-  MOZ_ASSERT(aFloat->GetParent() == mBlock ||
-             (aFloat->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT),
-             "float should be in this block unless it was marked as "
-             "pushed float");
-  if (aFloat->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT) {
+  if (aFloat->HasAnyStateBits(NS_FRAME_IS_PUSHED_FLOAT) ||
+      aFloat->GetParent() != mBlock) {
+    MOZ_ASSERT(aFloat->HasAnyStateBits(NS_FRAME_IS_PUSHED_FLOAT | NS_FRAME_FIRST_REFLOW),
+               "float should be in this block unless it was marked as "
+               "pushed float, or just inserted");
+    MOZ_ASSERT(aFloat->GetParent()->FirstContinuation() == mBlock->FirstContinuation());
     // If, in a previous reflow, the float was pushed entirely to
     // another column/page, we need to steal it back.  (We might just
     // push it again, though.)  Likewise, if that previous reflow
     // reflowed this block but not its next continuation, we might need
     // to steal it from our own float-continuations list.
     //
     // For more about pushed floats, see the comment above
     // nsBlockFrame::DrainPushedFloats.
-    nsBlockFrame *floatParent =
-      static_cast<nsBlockFrame*>(aFloat->GetParent());
+    auto* floatParent = static_cast<nsBlockFrame*>(aFloat->GetParent());
     floatParent->StealFrame(aFloat);
 
     aFloat->RemoveStateBits(NS_FRAME_IS_PUSHED_FLOAT);
 
     // Appending is fine, since if a float was pushed to the next
     // page/column, all later floats were also pushed.
     mBlock->mFloats.AppendFrame(mBlock, aFloat);
   }
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/1505817.html
@@ -0,0 +1,27 @@
+<style>
+  html {
+    word-spacing: calc(-47em + 255px);
+  }
+
+  * {
+    float: left;
+    column-count: 14;
+  }
+
+  *::first-letter {
+    -moz-margin-start: calc(25px*3);
+  }
+</style>
+<script>
+  function start() {
+    o1 = document.createElement('c')
+    audio = document.getElementById('audio_0')
+    audio.insertAdjacentText('beforebegin', 'Ù\n-†­ð†3ê')
+    audio.getClientRects()
+    audio.insertAdjacentElement('beforebegin', o1)
+    audio.getClientRects()
+  }
+
+  window.addEventListener('load', start)
+</script>
+<audio id="audio_0" muted>
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -711,8 +711,9 @@ load 1489287.html
 load 1489863.html
 load 1489770.html
 load 1490032.html
 load 1490685.html
 load 1493708.html
 load 1493710.html
 load 1493741.html
 load 1494380.html
+load 1505817.html