Bug 993936 - Make check for continuing session stricter. r=smaug
authorDmitry Rozhkov <dmitry.rojkov@gmail.com>
Thu, 24 Apr 2014 13:21:56 +0300
changeset 198557 114aa4935a4390e933593b39aaf8c65edef01eac
parent 198556 ace4dd4263499c5cc8592af910ae464ee212f87c
child 198558 4554b016a72be463cf960299b3e2381c28a00cff
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs993936
milestone31.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 993936 - Make check for continuing session stricter. r=smaug
layout/base/nsPresShell.cpp
layout/base/tests/mochitest.ini
layout/base/tests/test_bug993936.html
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6711,17 +6711,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
       uint32_t flags = 0;
       if (aEvent->message == NS_TOUCH_START) {
         flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
         WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
         // if this is a continuing session, ensure that all these events are
         // in the same document by taking the target of the events already in
         // the capture list
         nsCOMPtr<nsIContent> anyTarget;
-        if (gCaptureTouchList->Count() > 0) {
+        if (gCaptureTouchList->Count() > 0 && touchEvent->touches.Length() > 1) {
           gCaptureTouchList->Enumerate(&FindAnyTarget, &anyTarget);
         } else {
           gPreventMouseEvents = false;
         }
 
         for (int32_t i = touchEvent->touches.Length(); i; ) {
           --i;
           dom::Touch* touch = touchEvent->touches[i];
--- a/layout/base/tests/mochitest.ini
+++ b/layout/base/tests/mochitest.ini
@@ -48,16 +48,17 @@ support-files =
   bug570378-persian-3-ref.html
   bug570378-persian-4.html
   bug570378-persian-4-ref.html
   bug570378-persian-5.html
   bug570378-persian-5-ref.html
 
 [test_preserve3d_sorting_hit_testing.html]
 [test_after_paint_pref.html]
+[test_bug993936.html]
 skip-if = e10s
 [test_border_radius_hit_testing.html]
 [test_bug66619.html]
 [test_bug93077-1.html]
 [test_bug93077-2.html]
 [test_bug93077-3.html]
 [test_bug93077-4.html]
 [test_bug93077-5.html]
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/test_bug993936.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=993936
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 993936</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 993936 **/
+
+var currentId = 0;
+var evictedTouchesCount = 0;
+
+function testtouch(aOptions) {
+  if (!aOptions)
+    aOptions = {};
+  this.identifier = aOptions.identifier || 0;
+  this.target = aOptions.target || 0;
+  this.page = aOptions.page || {x: 0, y: 0};
+  this.radius = aOptions.radius || {x: 0, y: 0};
+  this.rotationAngle = aOptions.rotationAngle || 0;
+  this.force = aOptions.force || 1;
+}
+
+function touchEvent(aOptions) {
+  if (!aOptions) {
+    aOptions = {};
+  }
+  this.ctrlKey = aOptions.ctrlKey || false;
+  this.altKey = aOptions.altKey || false;
+  this.shiftKey = aOptions.shiftKey || false;
+  this.metaKey = aOptions.metaKey || false;
+  this.touches = aOptions.touches || [];
+  this.targetTouches = aOptions.targetTouches || [];
+  this.changedTouches = aOptions.changedTouches || [];
+}
+
+function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) {
+  var ids = [], xs=[], ys=[], rxs = [], rys = [],
+      rotations = [], forces = [];
+
+  for (var touchType of ["touches", "changedTouches", "targetTouches"]) {
+    for (var i = 0; i < aEvent[touchType].length; i++) {
+      if (ids.indexOf(aEvent[touchType][i].identifier) == -1) {
+        ids.push(aEvent[touchType][i].identifier);
+        xs.push(aEvent[touchType][i].page.x);
+        ys.push(aEvent[touchType][i].page.y);
+        rxs.push(aEvent[touchType][i].radius.x);
+        rys.push(aEvent[touchType][i].radius.y);
+        rotations.push(aEvent[touchType][i].rotationAngle);
+        forces.push(aEvent[touchType][i].force);
+      }
+    }
+  }
+  return windowUtils.sendTouchEvent(aType,
+                                    ids, xs, ys, rxs, rys,
+                                    rotations, forces,
+                                    ids.length, aModifiers, 0);
+}
+
+function getSingleTouchEventForTarget(target, cwu) {
+  currentId++;
+  var bcr = target.getBoundingClientRect();
+  var touch = new testtouch({
+    page: {x: Math.round(bcr.left + bcr.width/2),
+           y: Math.round(bcr.top  + bcr.height/2)},
+    target: target,
+    identifier: currentId,
+  });
+  var event = new touchEvent({
+    touches: [touch],
+    targetTouches: [touch],
+    changedTouches: [touch]
+  });
+  return event;
+}
+
+function getMultiTouchEventForTarget(target, cwu) {
+  currentId++;
+  var bcr = target.getBoundingClientRect();
+  var touch1 = new testtouch({
+    page: {x: Math.round(bcr.left + bcr.width/2),
+           y: Math.round(bcr.top  + bcr.height/2)},
+    target: target,
+    identifier: currentId,
+  });
+  currentId++;
+  var touch2 = new testtouch({
+    page: {x: Math.round(bcr.left + bcr.width),
+           y: Math.round(bcr.top  + bcr.height)},
+    target: target,
+    identifier: currentId,
+  });
+  var event = new touchEvent({
+    touches: [touch1, touch2],
+    targetTouches: [touch1, touch2],
+    changedTouches: [touch1, touch2]
+  });
+  return event;
+}
+
+function runTests() {
+  var cwu = SpecialPowers.getDOMWindowUtils(window);
+
+  var event1 = getMultiTouchEventForTarget(d0, cwu);
+  sendTouchEvent(cwu, "touchstart", event1, 0);
+  sendTouchEvent(cwu, "touchmove", event1, 0);
+  is(evictedTouchesCount, 0, "Still no evicted touches");
+
+  var event2 = getSingleTouchEventForTarget(d0, cwu);
+  sendTouchEvent(cwu, "touchstart", event2, 0);
+
+  // By now we should get touchend event
+  ok(evictedTouchesCount > 0, "Got evicted touch");
+
+  finishTest();
+}
+
+function finishTest() {
+  // Let window.onerror have a chance to fire
+  setTimeout(function() {
+    SimpleTest.finish();
+  }, 0);
+}
+
+SimpleTest.waitForExplicitFinish();
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=993936">Mozilla Bug 993936</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<div id="d0">
+    Test div
+</div>
+
+<script>
+var d0 = document.getElementById("d0");
+
+d0.addEventListener("touchend", function(ev) {
+  evictedTouchesCount++;
+});
+
+window.onload = function () {
+  setTimeout(function() {
+    runTests();
+  }, 0);
+}
+
+</script>
+</body>
+</html>