Bug 946632 - Don't scroll vertically by mouse-wheel on a single-line text control. r=bz
authorMats Palmgren <matspal@gmail.com>
Wed, 08 Jan 2014 16:05:41 -0500
changeset 178653 2d6cee5b1223629e603021d261e79eaa4cc36dda
parent 178652 9e38fe0101283605ac6d5af010a064b66c10778e
child 178654 ed17bd48a68bc19de4808655f3d9edf4977e37ca
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs946632
milestone29.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 946632 - Don't scroll vertically by mouse-wheel on a single-line text control. r=bz
content/events/src/nsEventStateManager.cpp
content/events/test/mochitest.ini
content/events/test/test_bug946632.html
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -29,16 +29,17 @@
 #include "nsIFormControl.h"
 #include "nsIComboboxControlFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMXULControlElement.h"
 #include "nsINameSpaceManager.h"
 #include "nsIBaseWindow.h"
 #include "nsISelection.h"
+#include "nsITextControlElement.h"
 #include "nsFrameSelection.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsIWebNavigation.h"
 #include "nsIContentViewer.h"
 #include "nsFrameManager.h"
 
 #include "nsIDOMXULElement.h"
@@ -2790,16 +2791,26 @@ nsEventStateManager::ComputeScrollTarget
                                       GetParentFrameToScroll(aTargetFrame);
   for (; scrollFrame; scrollFrame = GetParentFrameToScroll(scrollFrame)) {
     // Check whether the frame wants to provide us with a scrollable view.
     frameToScroll = scrollFrame->GetScrollTargetFrame();
     if (!frameToScroll) {
       continue;
     }
 
+    // Don't scroll vertically by mouse-wheel on a single-line text control.
+    if (checkIfScrollableY) {
+      nsIContent* c = scrollFrame->GetContent();
+      nsCOMPtr<nsITextControlElement> ctrl =
+        do_QueryInterface(c->IsInAnonymousSubtree() ? c->GetBindingParent() : c);
+      if (ctrl && ctrl->IsSingleLineTextControl()) {
+        continue;
+      }
+    }
+
     if (!checkIfScrollableX && !checkIfScrollableY) {
       return frameToScroll;
     }
 
     ScrollbarStyles ss = frameToScroll->GetScrollbarStyles();
     bool hiddenForV = (NS_STYLE_OVERFLOW_HIDDEN == ss.mVertical);
     bool hiddenForH = (NS_STYLE_OVERFLOW_HIDDEN == ss.mHorizontal);
     if ((hiddenForV && hiddenForH) ||
--- a/content/events/test/mochitest.ini
+++ b/content/events/test/mochitest.ini
@@ -82,16 +82,17 @@ skip-if = true # Disabled due to timeout
 [test_bug812744.html]
 [test_bug847597.html]
 [test_bug855741.html]
 [test_bug864040.html]
 [test_bug930374-content.html]
 [test_bug944847.html]
 skip-if = toolkit == "gonk"
 [test_bug944011.html]
+[test_bug946632.html]
 [test_clickevent_on_input.html]
 [test_continuous_wheel_events.html]
 [test_dblclick_explicit_original_target.html]
 [test_dom_keyboard_event.html]
 [test_dom_mouse_event.html]
 [test_dom_wheel_event.html]
 [test_draggableprop.html]
 [test_dragstart.html]
new file mode 100644
--- /dev/null
+++ b/content/events/test/test_bug946632.html
@@ -0,0 +1,139 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=946632
+-->
+<head>
+  <title>Test for bug 946632 - propagate mouse-wheel vertical scroll events to container</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <style>
+    .scrollable {
+      overflow: scroll;
+      height: 200px;
+      width: 200px;
+    }
+    input {
+      font-size: 72px;
+      height: 20px;
+      width: 20px;
+    }
+  </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946632">Mozilla Bug 946632</a>
+<p id="display"></p>
+<div id="container" class="scrollable">
+ <input value="value">
+ x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+</div>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests, window);
+
+var input = document.querySelector("input");
+var container = document.querySelector("#container");
+
+function prepare(check)
+{
+  container.scrollTop = 0;
+  container.scrollLeft = 0;
+  input.scrollTop = 0;
+  input.scrollLeft = 0;
+  container.style.display='none';
+  container.getBoundingClientRect();
+  container.style.display='';
+  container.getBoundingClientRect();
+  scrollHandler = function(event) {
+    window.removeEventListener("scroll", arguments.callee, true);
+    event.stopPropagation();
+    check(event)
+    setTimeout(nextTest,0);
+  };
+  window.addEventListener("scroll", scrollHandler, true);
+}
+
+var tests = [
+  { 
+    check: function(event) {
+      is(event.target, container, "<input> vertical line scroll targets container");
+      ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
+      is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
+      is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
+      is(input.scrollLeft, 0, "<input> horizontal line scroll input.scrollLeft");
+    },
+    test: function() {
+      synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
+                                     deltaY: 1.0, lineOrPageDeltaY: 1 });
+    }
+  },
+ { 
+    check: function(event) {
+      is(event.target, input, "<input> horizontal line scroll targets <input>");
+      is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
+      ok(input.scrollLeft > 0, "<input> horizontal line scroll input.scrollLeft");
+      is(container.scrollTop, 0, "<input> horizontal line scroll container.scrollTop");
+      is(container.scrollLeft, 0, "<input> horizontal line scroll container.scrollLeft");
+    },
+    test: function() {
+      synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_LINE,
+                                     deltaX: 1.0, lineOrPageDeltaX: 1 });
+    }
+  },
+ { 
+    check: function(event) {
+      is(event.target, container, "<input> vertical page scroll targets container");
+      ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
+      is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
+      is(input.scrollTop, 0, "<input> vertical page scroll input.scrollTop");
+      is(input.scrollLeft, 0, "<input> vertical page scroll input.scrollLeft");
+    },
+    test: function() {
+      synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+                                     deltaY: 1.0, lineOrPageDeltaY: 1 });
+    }
+  },
+ { 
+    check: function(event) {
+      is(event.target, input, "<input> horizontal page scroll targets <input>");
+      is(input.scrollTop, 0, "<input> horizontal page scroll input.scrollTop");
+      ok(input.scrollLeft > 0, "<input> horizontal page scroll input.scrollLeft");
+      is(container.scrollTop, 0, "<input> horizontal page scroll container.scrollTop");
+      is(container.scrollLeft, 0, "<input> horizontal page scroll container.scrollLeft");
+    },
+    test: function() {
+      synthesizeWheel(input, 5, 5, { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+                                     deltaX: 1.0, lineOrPageDeltaX: 1 });
+    }
+  },
+];
+
+var i = 0;
+function nextTest()
+{
+  if (i == tests.length) {
+    SimpleTest.finish();
+    return;
+  }
+  var test = tests[i];
+  ++i;
+  prepare(test.check);
+  test.test();
+}
+
+function runTests()
+{
+  nextTest();
+}
+
+</script>
+</pre>
+</body>
+</html>