Bug 1505817 - Handle the case where a float is dynamically inserted inside a continuation. r=dbaron
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 08 Nov 2018 21:37:16 +0000
changeset 445319 3d0711b3c764ac815d0cd74020710e25671faa19
parent 445318 eb5bb8dadeecff04f642c0244652bafe55cb418c
child 445320 bc748124b58b8860bb1bd1712c6e44f11c6587c9
push id109718
push userrgurzau@mozilla.com
push dateFri, 09 Nov 2018 05:49:16 +0000
treeherdermozilla-inbound@58c02c05d2db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1505817
milestone65.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 1505817 - Handle the case where a float is dynamically inserted inside a continuation. r=dbaron 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
@@ -712,8 +712,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