Propagate |aRemoveOnlyFluidContinuations| when removing continuations in other blocks. b=405178 r+sr=roc a=mtschrep
authormats.palmgren@bredband.net
Sat, 01 Dec 2007 02:47:58 -0800
changeset 8520 62cc9fe560de9d5a2dfe5f3f8c9e143d67171860
parent 8519 5e1ba80ae89a4d645f1ca01dc40f36c47c97f59a
child 8521 20d9205058328bf879cdc75d5addc19dfa48d211
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherderautoland@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmtschrep
bugs405178
milestone1.9b2pre
Propagate |aRemoveOnlyFluidContinuations| when removing continuations in other blocks. b=405178 r+sr=roc a=mtschrep
layout/generic/nsBlockFrame.cpp
layout/generic/test/Makefile.in
layout/generic/test/test_bug405178.html
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -5224,26 +5224,28 @@ nsBlockInFlowLineIterator::Prev()
         --mLine;
         return PR_TRUE;
       }
     }
     currentlyInOverflowLines = !currentlyInOverflowLines;
   }
 }
 
-static nsresult RemoveBlockChild(nsIFrame* aFrame, PRBool aDestroyFrames)
+static nsresult RemoveBlockChild(nsIFrame* aFrame, PRBool aDestroyFrames,
+                                 PRBool aRemoveOnlyFluidContinuations)
 {
   if (!aFrame)
     return NS_OK;
 
   nsBlockFrame* nextBlock = static_cast<nsBlockFrame*>(aFrame->GetParent());
   NS_ASSERTION(nextBlock->GetType() == nsGkAtoms::blockFrame ||
                nextBlock->GetType() == nsGkAtoms::areaFrame,
                "Our child's continuation's parent is not a block?");
-  return nextBlock->DoRemoveFrame(aFrame, aDestroyFrames);
+  return nextBlock->DoRemoveFrame(aFrame, aDestroyFrames,
+                                  aRemoveOnlyFluidContinuations);
 }
 
 // This function removes aDeletedFrame and all its continuations.  It
 // is optimized for deleting a whole series of frames. The easy
 // implementation would invoke itself recursively on
 // aDeletedFrame->GetNextContinuation, then locate the line containing
 // aDeletedFrame and remove aDeletedFrame from that line. But here we
 // start by locating aDeletedFrame and then scanning from that point
@@ -5290,17 +5292,18 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aD
     nsFrameList* overflowPlaceholders = GetOverflowPlaceholders();
     if (overflowPlaceholders && overflowPlaceholders->RemoveFrame(aDeletedFrame)) {
       nsIFrame* nif = aDeletedFrame->GetNextInFlow();
       if (aDestroyFrames) {
         aDeletedFrame->Destroy();
       } else {
         aDeletedFrame->SetNextSibling(nsnull);
       }
-      return RemoveBlockChild(nif, aDestroyFrames);
+      return RemoveBlockChild(nif, aDestroyFrames,
+                              aRemoveOnlyFluidContinuations);
     }
   }
   
   // Find the line and the previous sibling that contains
   // deletedFrame; we also find the pointer to the line.
   nsLineList::iterator line_start = mLines.begin(),
                        line_end = mLines.end();
   nsLineList::iterator line = line_start;
@@ -5450,17 +5453,18 @@ found_frame:;
         haveAdvancedToNextLine = PR_TRUE;
       }
     }
 
     if (deletedNextContinuation) {
       // Continuations for placeholder frames don't always appear in
       // consecutive lines. So for placeholders, just continue the slow easy way.
       if (isPlaceholder) {
-        return RemoveBlockChild(deletedNextContinuation, aDestroyFrames);
+        return RemoveBlockChild(deletedNextContinuation, aDestroyFrames,
+                                aRemoveOnlyFluidContinuations);
       }
 
       // See if we should keep looking in the current flow's line list.
       if (deletedNextContinuation->GetParent() != this) {
         // The deceased frames continuation is not a child of the
         // current block. So break out of the loop so that we advance
         // to the next parent.
         break;
@@ -5499,17 +5503,18 @@ found_frame:;
     line.next()->SetInvalidateTextRuns(PR_TRUE);
   }
 
 #ifdef DEBUG
   VerifyLines(PR_TRUE);
 #endif
 
   // Advance to next flow block if the frame has more continuations
-  return RemoveBlockChild(aDeletedFrame, aDestroyFrames);
+  return RemoveBlockChild(aDeletedFrame, aDestroyFrames,
+                          aRemoveOnlyFluidContinuations);
 }
 
 nsresult
 nsBlockFrame::StealFrame(nsPresContext* aPresContext,
                          nsIFrame*      aChild,
                          PRBool         aForceNormal)
 {
   NS_PRECONDITION(aPresContext && aChild, "null pointer");
--- a/layout/generic/test/Makefile.in
+++ b/layout/generic/test/Makefile.in
@@ -52,14 +52,15 @@ include $(topsrcdir)/config/rules.mk
 		test_bug384527.html \
 		test_bug385751.html \
 		test_bug389630.html \
 		test_bug391747.html \
 		test_bug392923.html \
 		test_bug394173.html \
 		test_bug394239.html \
 		test_bug402380.html \
+		test_bug405178.html \
 		test_character_movement.html \
 		test_word_movement.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/layout/generic/test/test_bug405178.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=405178
+-->
+<head>
+  <title>Test for Bug 405178</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=405178">Mozilla Bug 405178</a>
+<p id="display"><div id="div" style="-moz-column-width: 10px;">&#23377;&#1741; </div></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 405178 **/
+
+var div, textNode;
+
+function boom()
+{
+  div = document.getElementById("div");
+  textNode = div.firstChild;
+
+  div.removeChild(textNode);
+  setTimeout(boom2, 200);
+}
+
+function boom2()
+{
+  textNode.data = "";
+  div.appendChild(document.createTextNode("X"))
+  var foo = document.body.offsetHeight;
+
+  ok(true, "Test is successful if we get here without crashing");
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(boom);
+
+</script>
+</pre>
+</body>
+</html>
+