Bug 841192. Part 16: Take plugin's own clipping into account when computing the region for its window. Make SortByContentOrder handle cases where display items in the same list come from different documents. r=mattwoodrow
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 05 Apr 2013 21:30:34 +1300
changeset 127811 1e958f7224a737ac34be464a9e11e445c8d1b0df
parent 127810 3396e302a1e44e964f3dfeea457f26498acbdff4
child 127812 1f65b5204c8bcb45df6a2bfb7b2418ecb635cdab
push id24512
push userryanvm@gmail.com
push dateFri, 05 Apr 2013 20:13:49 +0000
treeherdermozilla-central@139b6ba547fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs841192
milestone23.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 841192. Part 16: Take plugin's own clipping into account when computing the region for its window. Make SortByContentOrder handle cases where display items in the same list come from different documents. r=mattwoodrow
layout/base/nsDisplayList.cpp
layout/generic/nsFrame.cpp
layout/generic/nsObjectFrame.cpp
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1390,28 +1390,57 @@ static void Sort(nsDisplayList* aList, i
          aCmp(list1.GetBottom(), list2.GetBottom(), aClosure))) {
       aList->AppendToTop(list1.RemoveBottom());
     } else {
       aList->AppendToTop(list2.RemoveBottom());
     }
   }
 }
 
+static nsIContent* FindContentInDocument(nsIContent* aContent, nsIDocument* aDoc) {
+  nsIContent* c = aContent;
+  for (;;) {
+    nsIDocument* d = c->OwnerDoc();
+    if (d == aDoc) {
+      return c;
+    }
+    nsIDocument* parentDoc = d->GetParentDocument();
+    if (!parentDoc) {
+      return nullptr;
+    }
+    c = parentDoc->FindContentForSubDocument(d);
+    if (!c) {
+      NS_ERROR("No content for subdocument?");
+      return nullptr;
+    }
+  }
+}
+
 static bool IsContentLEQ(nsDisplayItem* aItem1, nsDisplayItem* aItem2,
-                           void* aClosure) {
-  // These GetUnderlyingFrame calls return non-null because we're only used
-  // in sorting
-  return nsLayoutUtils::CompareTreePosition(
-      aItem1->GetUnderlyingFrame()->GetContent(),
-      aItem2->GetUnderlyingFrame()->GetContent(),
-      static_cast<nsIContent*>(aClosure)) <= 0;
+                         void* aClosure) {
+  nsIContent* commonAncestor = static_cast<nsIContent*>(aClosure);
+  // It's possible that the nsIContent for aItem1 or aItem2 is in a subdocument
+  // of commonAncestor, because display items for subdocuments have been
+  // mixed into the same list. Ensure that we're looking at content
+  // in commonAncestor's document.
+  nsIDocument* commonAncestorDoc = commonAncestor->OwnerDoc();
+  nsIContent* content1 = FindContentInDocument(aItem1->GetUnderlyingFrame()->GetContent(),
+                                               commonAncestorDoc);
+  nsIContent* content2 = FindContentInDocument(aItem2->GetUnderlyingFrame()->GetContent(),
+                                               commonAncestorDoc);
+  if (!content1 || !content2) {
+    NS_ERROR("Document trees are mixed up!");
+    // Something weird going on
+    return true;
+  }
+  return nsLayoutUtils::CompareTreePosition(content1, content2, commonAncestor) <= 0;
 }
 
 static bool IsZOrderLEQ(nsDisplayItem* aItem1, nsDisplayItem* aItem2,
-                          void* aClosure) {
+                        void* aClosure) {
   // These GetUnderlyingFrame calls return non-null because we're only used
   // in sorting.  Note that we can't just take the difference of the two
   // z-indices here, because that might overflow a 32-bit int.
   int32_t index1 = nsLayoutUtils::GetZIndex(aItem1->GetUnderlyingFrame());
   int32_t index2 = nsLayoutUtils::GetZIndex(aItem2->GetUnderlyingFrame());
   return index1 <= index2;
 }
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1882,17 +1882,23 @@ nsIFrame::BuildDisplayListForStackingCon
   resultList.AppendToTop(set.Floats());
   // 7: general content
   resultList.AppendToTop(set.Content());
   // 7.5: outlines, in content tree order. We need to sort by content order
   // because an element with outline that breaks and has children with outline
   // might have placed child outline items between its own outline items.
   // The element's outline items need to all come before any child outline
   // items.
-  set.Outlines()->SortByContentOrder(aBuilder, GetContent());
+  nsIContent* content = GetContent();
+  if (!content) {
+    content = PresContext()->Document()->GetRootElement();
+  }
+  if (content) {
+    set.Outlines()->SortByContentOrder(aBuilder, content);
+  }
 #ifdef DEBUG
   DisplayDebugBorders(aBuilder, this, set);
 #endif
   resultList.AppendToTop(set.Outlines());
   // 8, 9: non-negative z-index children
   resultList.AppendToTop(set.PositionedDescendants());
 
   if (!isTransformed) {
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -1053,19 +1053,18 @@ nsDisplayPlugin::ComputeVisibility(nsDis
       // Since transforms induce reference frames, we don't need to worry
       // about this method fluffing out due to non-rectilinear transforms.
       nsRect rAncestor = nsLayoutUtils::TransformFrameRectToAncestor(f,
           f->GetContentRectRelativeToSelf(), ReferenceFrame());
       nscoord appUnitsPerDevPixel =
         ReferenceFrame()->PresContext()->AppUnitsPerDevPixel();
       f->mNextConfigurationBounds = rAncestor.ToNearestPixels(appUnitsPerDevPixel);
 
-      bool snap;
       nsRegion visibleRegion;
-      visibleRegion.And(*aVisibleRegion, GetBounds(aBuilder, &snap));
+      visibleRegion.And(*aVisibleRegion, GetClippedBounds(aBuilder));
       // Make visibleRegion relative to f
       visibleRegion.MoveBy(-ToReferenceFrame());
 
       f->mNextConfigurationClipRegion.Clear();
       nsRegionRectIterator iter(visibleRegion);
       for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
         nsRect rAncestor =
           nsLayoutUtils::TransformFrameRectToAncestor(f, *r, ReferenceFrame());