Bug 1359709 - Use the DOM-ordering parent frame when deciding if a frame combines its transform with ancestors. r=dbaron
☠☠ backed out by 6a84d1b25433 ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 08 Jun 2017 15:24:03 +1200
changeset 411052 a3eec11c6b37419b1a700b2873d5a66b0db1e62d
parent 411051 5c606fafb195dc6f460ba27b5f56a594c017a863
child 411053 5ea810dbc4affeeffb3694b99609435075a25697
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1359709
milestone55.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 1359709 - Use the DOM-ordering parent frame when deciding if a frame combines its transform with ancestors. r=dbaron
dom/tests/mochitest/general/test_bug1313753.html
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
--- a/dom/tests/mochitest/general/test_bug1313753.html
+++ b/dom/tests/mochitest/general/test_bug1313753.html
@@ -46,16 +46,16 @@ SimpleTest.waitForFocus(runTest);
     height: 400px;
     width: 200px;
 }
 </style>
 <div id="outer">
   <div id="closure">
     <div style="transform-style: preserve-3d;">
 	<div style="transform-style: preserve-3d; background-color: blue;">
-	  <ul>
-	    <li><div id="target" class="panel"></div>
+	  <ul style="transform-style: preserve-3d;">
+	    <li style="transform-style:preserve-3d;"><div id="target" class="panel"></div>
 	    </li>
 	  </ul>
 	</div>
     </div>
   </div>
 </div>
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1388,17 +1388,18 @@ nsIFrame::Extend3DContext(const nsStyleD
          !nsSVGIntegrationUtils::UsingEffectsForFrame(this);
 }
 
 bool
 nsIFrame::Combines3DTransformWithAncestors(const nsStyleDisplay* aStyleDisplay,
                                            EffectSet* aEffectSet) const
 {
   MOZ_ASSERT(aStyleDisplay == StyleDisplay());
-  if (!GetParent() || !GetParent()->Extend3DContext(aEffectSet)) {
+  nsIFrame* parent = GetFlattenedTreeParentPrimaryFrame();
+  if (!parent || !parent->Extend3DContext()) {
     return false;
   }
   return IsTransformed(aStyleDisplay,aEffectSet) ||
          BackfaceIsHidden(aStyleDisplay);
 }
 
 bool
 nsIFrame::In3DContextAndBackfaceIsHidden(EffectSet* aEffectSet) const
@@ -2316,19 +2317,19 @@ CheckForApzAwareEventHandlers(nsDisplayL
 /**
  * True if aDescendant participates the context aAncestor participating.
  */
 static bool
 FrameParticipatesIn3DContext(nsIFrame* aAncestor, nsIFrame* aDescendant) {
   MOZ_ASSERT(aAncestor != aDescendant);
   MOZ_ASSERT(aAncestor->Extend3DContext());
   nsIFrame* frame;
-  for (frame = nsLayoutUtils::GetCrossDocParentFrame(aDescendant);
+  for (frame = aDescendant->GetFlattenedTreeParentPrimaryFrame();
        frame && aAncestor != frame;
-       frame = nsLayoutUtils::GetCrossDocParentFrame(frame)) {
+       frame = frame->GetFlattenedTreeParentPrimaryFrame()) {
     if (!frame->Extend3DContext()) {
       return false;
     }
   }
   MOZ_ASSERT(frame == aAncestor);
   return true;
 }
 
@@ -6273,16 +6274,26 @@ nsIFrame::GetNearestWidget(nsPoint& aOff
   nsPoint offsetToView;
   nsPoint offsetToWidget;
   nsIWidget* widget =
     GetClosestView(&offsetToView)->GetNearestWidget(&offsetToWidget);
   aOffset = offsetToView + offsetToWidget;
   return widget;
 }
 
+nsIFrame*
+nsIFrame::GetFlattenedTreeParentPrimaryFrame() const
+{
+  if (!GetContent()) {
+    return nullptr;
+  }
+  nsIContent* parent = GetContent()->GetFlattenedTreeParent();
+  return parent ? parent->GetPrimaryFrame() : nullptr;
+}
+
 Matrix4x4
 nsIFrame::GetTransformMatrix(const nsIFrame* aStopAtAncestor,
                              nsIFrame** aOutAncestor,
                              bool aInCSSUnits)
 {
   NS_PRECONDITION(aOutAncestor, "Need a place to put the ancestor!");
 
   /* If we're transformed, we want to hand back the combination
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -833,16 +833,22 @@ public:
 
   /**
    * Gets the parent of a frame, using the parent of the placeholder for
    * out-of-flow frames.
    */
   inline nsContainerFrame* GetInFlowParent();
 
   /**
+   * Gets the primary frame of the Content's flattened tree
+   * parent, if one exists.
+   */
+  inline nsIFrame* GetFlattenedTreeParentPrimaryFrame() const;
+
+  /**
    * Return the placeholder for this frame (which must be out-of-flow).
    * @note this will only return non-null if |this| is the first-in-flow
    * although we don't assert that here for legacy reasons.
    */
   inline nsPlaceholderFrame* GetPlaceholderFrame() const {
     MOZ_ASSERT(HasAnyStateBits(NS_FRAME_OUT_OF_FLOW));
     return GetProperty(PlaceholderFrameProperty());
   }