Bug 1387059 - When checking if nsDisplayPerspective participates in preserve-3d, check the underlying transformed frame. r=mstange
☠☠ backed out by bb7ce98c2f4a ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 25 Aug 2017 15:40:45 +1200
changeset 376728 61a168afa4368486fbeab563a21188d3ce57aa85
parent 376727 5c705cc6d5708d24e9f6648ca537bf110e62f305
child 376729 3b8bb2bc1ac06840ecb6e91f4cf59e2ea96d97f2
push id94146
push usermwoodrow@mozilla.com
push dateFri, 25 Aug 2017 03:44:52 +0000
treeherdermozilla-inbound@3b8bb2bc1ac0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1387059
milestone57.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 1387059 - When checking if nsDisplayPerspective participates in preserve-3d, check the underlying transformed frame. r=mstange
dom/tests/mochitest/general/mochitest.ini
dom/tests/mochitest/general/test_pointerPreserves3DPerspective.html
layout/generic/nsIFrame.h
layout/painting/nsDisplayList.cpp
--- a/dom/tests/mochitest/general/mochitest.ini
+++ b/dom/tests/mochitest/general/mochitest.ini
@@ -111,16 +111,17 @@ support-files = test_offsets.js
 [test_outerHTML.xhtml]
 [test_paste_selection.html]
 [test_performance_now.html]
 [test_performance_timeline.html]
 [test_picture_apng.html]
 [test_picture_mutations.html]
 [test_pointerPreserves3D.html]
 [test_pointerPreserves3DClip.html]
+[test_pointerPreserves3DPerspective.html]
 [test_resource_timing.html]
 [test_resource_timing_cross_origin.html]
 [test_resource_timing_frameset.html]
 [test_selectevents.html]
 skip-if = toolkit == 'android' # bug 1230232 - Mouse doesn't select in the same way
 [test_showModalDialog_removed.html]
 [test_storagePermissionsAccept.html]
 [test_storagePermissionsLimitForeign.html]
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/general/test_pointerPreserves3DPerspective.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for pointer events with preserve-3d</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<div>
+  <div>
+    <div style="perspective: 100px; transform-style:preserve-3d; transform: translateX(100px)">
+      <div style="display:inline">
+        <div id="color" style="transform-style:flat; transform: translateX(-100px); display: block; background-color: blue; width: 200px; height: 200px;"></div>
+      </div>
+    </div>
+  </div>
+</div>
+<script class="testbody" type="text/javascript">
+function runTest() {
+    var target = document.elementFromPoint(200, 200);
+    ok(target == document.getElementById("color"), "Find the right target.");
+    var target = document.elementFromPoint(16, 16);
+    ok(target == document.getElementById("color"), "Find the right target.");
+}
+
+runTest();
+</script>
+</body>
+</html>
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -860,17 +860,17 @@ public:
    * 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;
+  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));
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2503,17 +2503,17 @@ void nsDisplayList::HitTest(nsDisplayLis
 
     bool snap;
     nsRect r = item->GetBounds(aBuilder, &snap).Intersect(aRect);
     auto itemType = item->GetType();
     bool same3DContext =
       (itemType == DisplayItemType::TYPE_TRANSFORM &&
        static_cast<nsDisplayTransform*>(item)->IsParticipating3DContext()) ||
       (itemType == DisplayItemType::TYPE_PERSPECTIVE &&
-       item->Frame()->Extend3DContext());
+       static_cast<nsDisplayPerspective*>(item)->TransformFrame()->Extend3DContext());
     if (same3DContext &&
         (itemType != DisplayItemType::TYPE_TRANSFORM ||
          !static_cast<nsDisplayTransform*>(item)->IsLeafOf3DContext())) {
       if (!item->GetClip().MayIntersect(aRect)) {
         continue;
       }
       AutoTArray<nsIFrame*, 1> neverUsed;
       // Start gethering leaves of the 3D rendering context, and
@@ -7524,21 +7524,21 @@ nsDisplayTransform::GetResultingTransfor
     if (ComputePerspectiveMatrix(frame, aAppUnitsPerPixel, perspectiveMatrix)) {
       result *= perspectiveMatrix;
     }
   }
 
   if ((aFlags & INCLUDE_PRESERVE3D_ANCESTORS) &&
       frame && frame->Combines3DTransformWithAncestors()) {
     // Include the transform set on our parent
-    NS_ASSERTION(frame->GetParent() &&
-                 frame->GetParent()->IsTransformed() &&
-                 frame->GetParent()->Extend3DContext(),
+    nsIFrame* parentFrame = frame->GetFlattenedTreeParentPrimaryFrame();
+    NS_ASSERTION(parentFrame && parentFrame->IsTransformed() &&
+                 parentFrame->Extend3DContext(),
                  "Preserve3D mismatch!");
-    FrameTransformProperties props(frame->GetParent(),
+    FrameTransformProperties props(parentFrame,
                                    aAppUnitsPerPixel,
                                    nullptr);
 
     uint32_t flags = aFlags & (INCLUDE_PRESERVE3D_ANCESTORS|INCLUDE_PERSPECTIVE);
 
     // If this frame isn't transformed (but we exist for backface-visibility),
     // then we're not a reference frame so no offset to origin will be added.
     // Otherwise we need to manually translate into our parent's coordinate
@@ -7773,17 +7773,17 @@ nsDisplayTransform::GetAccumulatedPreser
     if (!IsLeafOf3DContext()) {
       mTransformPreserves3D = GetTransform();
       return mTransformPreserves3D;
     }
 
     const nsIFrame* establisher; // Establisher of the 3D rendering context.
     for (establisher = mFrame;
          establisher && establisher->Combines3DTransformWithAncestors();
-         establisher = nsLayoutUtils::GetCrossDocParentFrame(establisher)) {
+         establisher = establisher->GetFlattenedTreeParentPrimaryFrame()) {
     }
     const nsIFrame* establisherReference =
       aBuilder->FindReferenceFrameFor(nsLayoutUtils::GetCrossDocParentFrame(establisher));
 
     nsPoint offset = establisher->GetOffsetToCrossDoc(establisherReference);
     float scale = mFrame->PresContext()->AppUnitsPerDevPixel();
     uint32_t flags = INCLUDE_PRESERVE3D_ANCESTORS|INCLUDE_PERSPECTIVE|OFFSET_BY_ORIGIN;
     mTransformPreserves3D =