Bug 519693, <select> click and drag scrolling not working, change to get scrollable frame when capturing, r=roc
authorNeil Deakin <neil@mozilla.com>
Fri, 09 Oct 2009 09:35:20 -0400
changeset 33710 7a931f8811fa709bb6e2eba48e5393b46e9b3c9f
parent 33709 fcaa766c0991e8f541d0affd73f9e325e80d1bf5
child 33711 162daefc8007ef4a7971def1a3c7e4fc12aae3d5
push id9641
push userneil@mozilla.com
push dateFri, 09 Oct 2009 13:38:00 +0000
treeherdermozilla-central@7a931f8811fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs519693
milestone1.9.3a1pre
Bug 519693, <select> click and drag scrolling not working, change to get scrollable frame when capturing, r=roc
layout/base/nsPresShell.cpp
toolkit/content/tests/widgets/test_mousecapture.xul
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6157,25 +6157,34 @@ PresShell::HandleEvent(nsIView         *
         }
       }
 #endif
     }
 
     PRBool captureRetarget = PR_FALSE;
     if (capturingContent) {
       captureRetarget = gCaptureInfo.mRetargetToElement;
-      // special case for <select> as it needs to capture on the dropdown list,
-      // so get the frame for the dropdown list instead.
-      if (!captureRetarget && capturingContent->Tag() == nsGkAtoms::select &&
-          capturingContent->IsHTML()) {
-        nsIFrame* selectFrame = GetPrimaryFrameFor(capturingContent);
-        if (selectFrame) {
-          nsIFrame* childframe = selectFrame->GetChildList(nsGkAtoms::selectPopupList).FirstChild();
-          if (childframe) {
-            frame = childframe;
+      if (!captureRetarget) {
+        nsIFrame* captureFrame = GetPrimaryFrameFor(capturingContent);
+        if (captureFrame) {
+          if (capturingContent->Tag() == nsGkAtoms::select &&
+              capturingContent->IsHTML()) {
+            // a dropdown <select> has a child in its selectPopupList and we should
+            // capture on that instead.
+            nsIFrame* childFrame = captureFrame->GetChildList(nsGkAtoms::selectPopupList).FirstChild();
+            if (childFrame) {
+              captureFrame = childFrame;
+            }
+          }
+
+          // scrollable frames should use the scrolling container as
+          // the root instead of the document
+          nsIScrollableFrame* scrollFrame = do_QueryFrame(captureFrame);
+          if (scrollFrame) {
+            frame = scrollFrame->GetScrolledFrame();
           }
         }
       }
     }
 
     // Get the frame at the event point. However, don't do this if we're
     // capturing and retargeting the event because the captured frame will
     // be used instead below.
--- a/toolkit/content/tests/widgets/test_mousecapture.xul
+++ b/toolkit/content/tests/widgets/test_mousecapture.xul
@@ -148,16 +148,22 @@ function runTests()
   previousWidth = frames[1].frames[0].document.documentElement.clientWidth;
   originalWidth = previousWidth;
   runCaptureTest(frames[1].document.documentElement.lastChild, framesetCallback);
 
   // ensure that clicking on an element where the frame disappears doesn't crash
   synthesizeMouse(frames[2].document.getElementById("input"), 8, 8, { type: "mousedown" }, frames[2]);
   synthesizeMouse(frames[2].document.getElementById("input"), 8, 8, { type: "mouseup" }, frames[2]);
 
+  synthesizeMouse(document.getElementById("option3"), 2, 2, { type: "mousedown" });
+  synthesizeMouse(document.getElementById("option3"), 2, 1000, { type: "mousemove" });
+  var select = document.getElementById("select");
+  is(select.selectedIndex, 9, "scroll select");
+  synthesizeMouse(document.getElementById("select"), 2, 2, { type: "mouseup" });
+
   // check to ensure that selection dragging scrolls the right scrollable area
   otherWindow = window.open("data:text/html,<html><p style='margin-top: 4000px'>This is some text</p></html>", "_blank");
   SimpleTest.waitForFocus(selectionScrollCheck, otherWindow);
 }
 
 function runCaptureTest(element, callback)
 {
   var expectedTarget = null;
@@ -249,15 +255,28 @@ SimpleTest.waitForFocus(runTests);
   <iframe width="100" height="100"
           src="data:text/html,%3Cbody style%3D'font-size%3A 40pt%3B'%3E.%3Cb id%3D'b'%3EThis%3C/b%3E is some text%3Cdiv id='fixed' style='position: fixed; left: 55px; top: 5px; width: 10px; height: 10px'%3E.%3C/div%3E%3C/body%3E"/>
 
   <iframe width="100" height="100"
           src="data:text/html,%3Cframeset cols='50%, 50%'%3E%3Cframe src='about:blank'%3E%3Cframe src='about:blank'%3E%3C/frameset%3E"/>
 
   <iframe width="100" height="100"
           src="data:text/html,%3Cinput id='input' onfocus='this.style.display = &quot;none&quot;' style='float: left;'"/>
+
+  <select id="select" xmlns="http://www.w3.org/1999/xhtml" size="4">
+    <option id="option1">One</option>
+    <option id="option2">Two</option>
+    <option id="option3">Three</option>
+    <option id="option4">Four</option>
+    <option id="option5">Five</option>
+    <option id="option6">Six</option>
+    <option id="option7">Seven</option>
+    <option id="option8">Eight</option>
+    <option id="option9">Nine</option>
+    <option id="option10">Ten</option>
+  </select>
 </hbox>
 
 <body id="body" xmlns="http://www.w3.org/1999/xhtml">
   <p id="display"/><div id="content" style="display: none"/><pre id="test"/>
 </body>
 
 </window>