Backout 1ebc3b1b8feb, 205c1c846d70 (bug 801488), and e4367fd2043f (bug 804323) due to b-c crashes.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 25 Oct 2012 07:53:36 -0400
changeset 111509 293bdc2afe11f479e8394229f04281abe13ceb25
parent 111508 2b4de3ace7a501a5facf0be6d037dd54071303b1
child 111510 c2d82d7c1dbc0f8005617a7eeae787df2b6e1662
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
bugs801488, 804323
milestone19.0a1
backs out1ebc3b1b8feb8eb7c3e24a7772b66a462c6b9fa9
Backout 1ebc3b1b8feb, 205c1c846d70 (bug 801488), and e4367fd2043f (bug 804323) due to b-c crashes.
layout/base/nsCSSFrameConstructor.cpp
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/reftests/bugs/804323-1-ref.html
layout/reftests/bugs/804323-1.html
layout/reftests/bugs/reftest.list
layout/xul/base/src/nsSplitterFrame.cpp
layout/xul/base/src/nsStackLayout.cpp
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -8144,33 +8144,23 @@ nsCSSFrameConstructor::ProcessRestyledFr
         continue;
     }
 
     if ((hint & nsChangeHint_AddOrRemoveTransform) && frame &&
         !(hint & nsChangeHint_ReconstructFrame)) {
       if (NeedToReframeForAddingOrRemovingTransform(frame)) {
         NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
       } else {
-        // Normally frame construction would set state bits as needed,
-        // but we're not going to reconstruct the frame so we need to set them.
-        // It's because we need to set this state on each affected frame
+        // We can just add this state bit unconditionally, since it's
+        // conservative. Normally frame construction would set this if needed,
+        // but we're not going to reconstruct the frame so we need to set it.
+        // It's because we need to set this bit on each affected frame
         // that we can't coalesce nsChangeHint_AddOrRemoveTransform hints up
         // to ancestors (i.e. it can't be an inherited change hint).
-        if (frame->IsPositioned()) {
-          // If a transform has been added, we'll be taking this path,
-          // but we may be taking this path even if a transform has been
-          // removed. It's OK to add the bit even if it's not needed.
-          frame->AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
-          frame->MarkAsAbsoluteContainingBlock();
-        } else {
-          // Don't remove NS_FRAME_MAY_BE_TRANSFORMED since it may still by
-          // transformed by other means. It's OK to have the bit even if it's
-          // not needed.
-          frame->MarkAsNotAbsoluteContainingBlock();
-        }
+        frame->AddStateBits(NS_FRAME_MAY_BE_TRANSFORMED);
       }
     }
     if (hint & nsChangeHint_ReconstructFrame) {
       // If we ever start passing true here, be careful of restyles
       // that involve a reframe and animations.  In particular, if the
       // restyle we're processing here is an animation restyle, but
       // the style resolution we will do for the frame construction
       // happens async when we're not in an animation restyle already,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -244,31 +244,22 @@ nsIFrame::GetAbsoluteContainingBlock() c
   NS_ASSERTION(IsAbsoluteContainer(), "The frame is not marked as an abspos container correctly");
   nsAbsoluteContainingBlock* absCB = static_cast<nsAbsoluteContainingBlock*>
     (Properties().Get(AbsoluteContainingBlockProperty()));
   NS_ASSERTION(absCB, "The frame is marked as an abspos container but doesn't have the property");
   return absCB;
 }
 
 void
-nsIFrame::MarkAsAbsoluteContainingBlock()
-{
+nsIFrame::MarkAsAbsoluteContainingBlock() {
   AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
   Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID()));
 }
 
 void
-nsIFrame::MarkAsNotAbsoluteContainingBlock()
-{
-  NS_ASSERTION(!HasAbsolutelyPositionedChildren(), "Think of the children!");
-  RemoveStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
-  Properties().Delete(AbsoluteContainingBlockProperty());
-}
-
-void
 nsIFrame::ClearDisplayItemCache()
 {
   if (GetStateBits() & NS_FRAME_HAS_CACHED_BACKGROUND) {
     Properties().Delete(CachedBackgroundImage());
     RemoveStateBits(NS_FRAME_HAS_CACHED_BACKGROUND);
   }
 }
 
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2865,18 +2865,17 @@ NS_PTR_TO_INT32(frame->Properties().Get(
   }  
 
   /**
    * Accessors for the absolute containing block.
    */
   bool IsAbsoluteContainer() const { return !!(mState & NS_FRAME_HAS_ABSPOS_CHILDREN); }
   bool HasAbsolutelyPositionedChildren() const;
   nsAbsoluteContainingBlock* GetAbsoluteContainingBlock() const;
-  void MarkAsAbsoluteContainingBlock();
-  void MarkAsNotAbsoluteContainingBlock();
+  virtual void MarkAsAbsoluteContainingBlock();
   // Child frame types override this function to select their own child list name
   virtual mozilla::layout::FrameChildListID GetAbsoluteListID() const { return kAbsoluteList; }
 
   // Checks if we (or any of our descendents) have NS_FRAME_PAINTED_THEBES set, and
   // clears this bit if so.
   bool CheckAndClearPaintedState();
 
   // CSS visibility just doesn't cut it because it doesn't inherit through
deleted file mode 100644
--- a/layout/reftests/bugs/804323-1-ref.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<style>
-body { margin:0; padding:0; overflow:hidden; }
-#new {
-  position: absolute;
-  left: 200px;
-  top: 100px;
-  width: 100px;
-  height: 100px;
-  background: yellow;
-}
-</style>
-</head>
-<body>
-<div id="new"></div>
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/804323-1.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<style>
-body { margin:0; padding:0; overflow:hidden; }
-#new {
-  position: absolute;
-  left: 100px;
-  top: 100px;
-  width: 100px;
-  height: 100px;
-  background: yellow;
-}
-</style>
-</head>
-<body>
-<div id="new" style="display:none"></div>
-<script>
-document.body.getBoundingClientRect().height;
-document.body.style.transform = "translateX(100px)";
-document.body.getBoundingClientRect().width;
-document.getElementById("new").style.display = "";
-</script>
-</body>
-</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1721,9 +1721,8 @@ fuzzy-if(true,17,5859) == 759036-2.html 
 == 776265-2a.html 776265-2-ref.html
 == 776265-2b.html 776265-2-ref.html
 == 776265-2c.html 776265-2-ref.html
 == 776265-2d.html 776265-2-ref.html
 == 787947-1.html 787947-1-ref.html
 fuzzy(40,800) == 797797-1.html 797797-1-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
 fuzzy(40,800) == 797797-2.html 797797-2-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
 == 801994-1.html 801994-1-ref.html
-== 804323-1.html 804323-1-ref.html
--- a/layout/xul/base/src/nsSplitterFrame.cpp
+++ b/layout/xul/base/src/nsSplitterFrame.cpp
@@ -896,16 +896,20 @@ nsSplitterFrameInner::EnsureOrient()
 void
 nsSplitterFrameInner::AdjustChildren(nsPresContext* aPresContext)
 {
   EnsureOrient();
   bool isHorizontal = !mOuter->IsHorizontal();
 
   AdjustChildren(aPresContext, mChildInfosBefore, mChildInfosBeforeCount, isHorizontal);
   AdjustChildren(aPresContext, mChildInfosAfter, mChildInfosAfterCount, isHorizontal);
+   
+   // printf("----- Posting Dirty -----\n");
+
+  aPresContext->PresShell()->FlushPendingNotifications(Flush_Display);
 }
 
 static nsIFrame* GetChildBoxForContent(nsIFrame* aParentBox, nsIContent* aContent)
 {
   nsIFrame* childBox = aParentBox->GetChildBox();
 
   while (nullptr != childBox) {
     if (childBox->GetContent() == aContent) {
--- a/layout/xul/base/src/nsStackLayout.cpp
+++ b/layout/xul/base/src/nsStackLayout.cpp
@@ -335,31 +335,42 @@ nsStackLayout::Layout(nsIFrame* aBox, ns
 
           // Now place the child.
           child->SetBounds(aState, childRect);
 
           // Flow the child.
           child->Layout(aState);
 
           // Get the child's new rect.
-          childRect = child->GetRect();
+          nsRect childRectNoMargin;
+          childRectNoMargin = childRect = child->GetRect();
           childRect.Inflate(margin);
 
           if (child->GetStyleXUL()->mStretchStack) {
             // Did the child push back on us and get bigger?
             if (offset.LeftRight() + childRect.width > clientRect.width) {
               clientRect.width = childRect.width + offset.LeftRight();
               grow = true;
             }
 
             if (offset.TopBottom() + childRect.height > clientRect.height) {
               clientRect.height = childRect.height + offset.TopBottom();
               grow = true;
             }
           }
+
+          if (!childRectNoMargin.IsEqualInterior(oldRect))
+          {
+            // redraw the new and old positions if the 
+            // child moved or resized.
+            // if the new and old rect intersect meaning we just moved a little
+            // then just redraw the union. If they don't intersect (meaning
+            // we moved a good distance) redraw both separately.
+            aBox->Redraw(aState);
+          }
        }
 
        child = child->GetNextBox();
      }
    } while (grow);
    
    // if some HTML inside us got bigger we need to force ourselves to
    // get bigger