Bug 925199 - Move touch-events.js to /toolkit. r=ochameau
authorPaul Rouget <paul@mozilla.com>
Fri, 11 Oct 2013 12:00:01 -0400
changeset 164304 5836dc9eaa656426be9771e30b3769b518c243a6
parent 164303 012fc96d11a00b5885410472c1c6148c2f3e928f
child 164305 b4f347a62071149e59562aba128b488437c8df1d
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs925199
milestone27.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 925199 - Move touch-events.js to /toolkit. r=ochameau
browser/devtools/responsivedesign/responsivedesign.jsm
browser/devtools/shared/touch-events.js
toolkit/devtools/Loader.jsm
toolkit/devtools/touch-events.js
--- a/browser/devtools/responsivedesign/responsivedesign.jsm
+++ b/browser/devtools/responsivedesign/responsivedesign.jsm
@@ -10,17 +10,17 @@ const Cu = Components.utils;
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/devtools/gDevTools.jsm");
 Cu.import("resource:///modules/devtools/FloatingScrollbars.jsm");
 Cu.import("resource:///modules/devtools/shared/event-emitter.js");
 
 var require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
 let Telemetry = require("devtools/shared/telemetry");
-let {TouchEventHandler} = require("devtools/shared/touch-events");
+let {TouchEventHandler} = require("devtools/touch-events");
 
 this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"];
 
 const MIN_WIDTH = 50;
 const MIN_HEIGHT = 50;
 
 const MAX_WIDTH = 10000;
 const MAX_HEIGHT = 10000;
deleted file mode 100644
--- a/browser/devtools/shared/touch-events.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-let {CC, Cc, Ci, Cu, Cr} = require('chrome');
-
-Cu.import('resource://gre/modules/Services.jsm');
-
-let handlerCount = 0;
-
-let orig_w3c_touch_events = Services.prefs.getIntPref('dom.w3c_touch_events.enabled');
-
-// =================== Touch ====================
-// Simulate touch events on desktop
-function TouchEventHandler (window) {
-  let contextMenuTimeout = 0;
-
-  // This guard is used to not re-enter the events processing loop for
-  // self dispatched events
-  let ignoreEvents = false;
-
-  let threshold = 25;
-  try {
-    threshold = Services.prefs.getIntPref('ui.dragThresholdX');
-  } catch(e) {}
-
-  let delay = 500;
-  try {
-    delay = Services.prefs.getIntPref('ui.click_hold_context_menus.delay');
-  } catch(e) {}
-
-  let TouchEventHandler = {
-    enabled: false,
-    events: ['mousedown', 'mousemove', 'mouseup', 'click'],
-    start: function teh_start() {
-      let isReloadNeeded = Services.prefs.getIntPref('dom.w3c_touch_events.enabled') != 1;
-      handlerCount++;
-      Services.prefs.setIntPref('dom.w3c_touch_events.enabled', 1);
-      this.enabled = true;
-      this.events.forEach((function(evt) {
-        window.addEventListener(evt, this, true);
-      }).bind(this));
-      return isReloadNeeded;
-    },
-    stop: function teh_stop() {
-      handlerCount--;
-      if (handlerCount == 0)
-        Services.prefs.setIntPref('dom.w3c_touch_events.enabled', orig_w3c_touch_events);
-      this.enabled = false;
-      this.events.forEach((function(evt) {
-        window.removeEventListener(evt, this, true);
-      }).bind(this));
-    },
-    handleEvent: function teh_handleEvent(evt) {
-      if (evt.button || ignoreEvents ||
-          evt.mozInputSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN)
-        return;
-
-      // The gaia system window use an hybrid system even on the device which is
-      // a mix of mouse/touch events. So let's not cancel *all* mouse events
-      // if it is the current target.
-      let content = evt.target.ownerDocument.defaultView;
-      let isSystemWindow = content.location.toString().indexOf("system.gaiamobile.org") != -1;
-
-      let eventTarget = this.target;
-      let type = '';
-      switch (evt.type) {
-        case 'mousedown':
-          this.target = evt.target;
-
-          contextMenuTimeout =
-            this.sendContextMenu(evt.target, evt.pageX, evt.pageY, delay);
-
-          this.cancelClick = false;
-          this.startX = evt.pageX;
-          this.startY = evt.pageY;
-
-          // Capture events so if a different window show up the events
-          // won't be dispatched to something else.
-          evt.target.setCapture(false);
-
-          type = 'touchstart';
-          break;
-
-        case 'mousemove':
-          if (!eventTarget)
-            return;
-
-          if (!this.cancelClick) {
-            if (Math.abs(this.startX - evt.pageX) > threshold ||
-                Math.abs(this.startY - evt.pageY) > threshold) {
-              this.cancelClick = true;
-              content.clearTimeout(contextMenuTimeout);
-            }
-          }
-
-          type = 'touchmove';
-          break;
-
-        case 'mouseup':
-          if (!eventTarget)
-            return;
-          this.target = null;
-
-          content.clearTimeout(contextMenuTimeout);
-          type = 'touchend';
-          break;
-
-        case 'click':
-          // Mouse events has been cancelled so dispatch a sequence
-          // of events to where touchend has been fired
-          evt.preventDefault();
-          evt.stopImmediatePropagation();
-
-          if (this.cancelClick)
-            return;
-
-          ignoreEvents = true;
-          content.setTimeout(function dispatchMouseEvents(self) {
-            self.fireMouseEvent('mousedown', evt);
-            self.fireMouseEvent('mousemove', evt);
-            self.fireMouseEvent('mouseup', evt);
-            ignoreEvents = false;
-         }, 0, this);
-
-          return;
-      }
-
-      let target = eventTarget || this.target;
-      if (target && type) {
-        this.sendTouchEvent(evt, target, type);
-      }
-
-      if (!isSystemWindow) {
-        evt.preventDefault();
-        evt.stopImmediatePropagation();
-      }
-    },
-    fireMouseEvent: function teh_fireMouseEvent(type, evt)  {
-      let content = evt.target.ownerDocument.defaultView;
-      var utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
-                         .getInterface(Ci.nsIDOMWindowUtils);
-      utils.sendMouseEvent(type, evt.clientX, evt.clientY, 0, 1, 0, true);
-    },
-    sendContextMenu: function teh_sendContextMenu(target, x, y, delay) {
-      let doc = target.ownerDocument;
-      let evt = doc.createEvent('MouseEvent');
-      evt.initMouseEvent('contextmenu', true, true, doc.defaultView,
-                         0, x, y, x, y, false, false, false, false,
-                         0, null);
-
-      let content = target.ownerDocument.defaultView;
-      let timeout = content.setTimeout((function contextMenu() {
-        target.dispatchEvent(evt);
-        this.cancelClick = true;
-      }).bind(this), delay);
-
-      return timeout;
-    },
-    sendTouchEvent: function teh_sendTouchEvent(evt, target, name) {
-      let document = target.ownerDocument;
-      let content = document.defaultView;
-
-      let touchEvent = document.createEvent('touchevent');
-      let point = document.createTouch(content, target, 0,
-                                       evt.pageX, evt.pageY,
-                                       evt.screenX, evt.screenY,
-                                       evt.clientX, evt.clientY,
-                                       1, 1, 0, 0);
-      let touches = document.createTouchList(point);
-      let targetTouches = touches;
-      let changedTouches = touches;
-      touchEvent.initTouchEvent(name, true, true, content, 0,
-                                false, false, false, false,
-                                touches, targetTouches, changedTouches);
-      target.dispatchEvent(touchEvent);
-      return touchEvent;
-    }
-  };
-
-  return TouchEventHandler;
-}
-
-exports.TouchEventHandler = TouchEventHandler;
--- a/toolkit/devtools/Loader.jsm
+++ b/toolkit/devtools/Loader.jsm
@@ -55,16 +55,17 @@ var BuiltinProvider = {
         "": "resource://gre/modules/commonjs/",
         "main": "resource:///modules/devtools/main.js",
         "devtools": "resource:///modules/devtools",
         "devtools/server": "resource://gre/modules/devtools/server",
         "devtools/toolkit/webconsole": "resource://gre/modules/devtools/toolkit/webconsole",
         "devtools/app-actor-front": "resource://gre/modules/devtools/app-actor-front.js",
         "devtools/styleinspector/css-logic": "resource://gre/modules/devtools/styleinspector/css-logic",
         "devtools/css-color": "resource://gre/modules/devtools/css-color",
+        "devtools/touch-events": "resource://gre/modules/devtools/touch-events",
         "devtools/client": "resource://gre/modules/devtools/client",
 
         "escodegen": "resource://gre/modules/devtools/escodegen",
         "estraverse": "resource://gre/modules/devtools/escodegen/estraverse",
 
         // Allow access to xpcshell test items from the loader.
         "xpcshell-test": "resource://test"
       },
@@ -97,33 +98,34 @@ var SrcdirProvider = {
     let toolkitDir = OS.Path.join(srcdir, "toolkit", "devtools");
     let mainURI = this.fileURI(OS.Path.join(devtoolsDir, "main.js"));
     let devtoolsURI = this.fileURI(devtoolsDir);
     let serverURI = this.fileURI(OS.Path.join(toolkitDir, "server"));
     let webconsoleURI = this.fileURI(OS.Path.join(toolkitDir, "webconsole"));
     let appActorURI = this.fileURI(OS.Path.join(toolkitDir, "apps", "app-actor-front.js"));
     let cssLogicURI = this.fileURI(OS.Path.join(toolkitDir, "styleinspector", "css-logic"));
     let cssColorURI = this.fileURI(OS.Path.join(toolkitDir, "css-color"));
+    let touchEventsURI = this.fileURI(OS.Path.join(toolkitDir, "touch-events"));
     let clientURI = this.fileURI(OS.Path.join(toolkitDir, "client"));
     let escodegenURI = this.fileURI(OS.Path.join(toolkitDir, "escodegen"));
     let estraverseURI = this.fileURI(OS.Path.join(toolkitDir, "escodegen", "estraverse"));
     this.loader = new loader.Loader({
       modules: {
         "toolkit/loader": loader,
         "source-map": SourceMap,
       },
       paths: {
         "": "resource://gre/modules/commonjs/",
         "main": mainURI,
         "devtools": devtoolsURI,
         "devtools/server": serverURI,
         "devtools/toolkit/webconsole": webconsoleURI,
         "devtools/app-actor-front": appActorURI,
         "devtools/styleinspector/css-logic": cssLogicURI,
-        "devtools/css-color": cssColorURI,
+        "devtools/touch-events": touchEventsURI,
         "devtools/client": clientURI,
         "escodegen": escodegenURI,
         "estraverse": estraverseURI
       },
       globals: loaderGlobals
     });
 
     return this._writeManifest(devtoolsDir).then(null, Cu.reportError);
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/touch-events.js
@@ -0,0 +1,185 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+let {CC, Cc, Ci, Cu, Cr} = require('chrome');
+
+Cu.import('resource://gre/modules/Services.jsm');
+
+let handlerCount = 0;
+
+let orig_w3c_touch_events = Services.prefs.getIntPref('dom.w3c_touch_events.enabled');
+
+// =================== Touch ====================
+// Simulate touch events on desktop
+function TouchEventHandler (window) {
+  let contextMenuTimeout = 0;
+
+  // This guard is used to not re-enter the events processing loop for
+  // self dispatched events
+  let ignoreEvents = false;
+
+  let threshold = 25;
+  try {
+    threshold = Services.prefs.getIntPref('ui.dragThresholdX');
+  } catch(e) {}
+
+  let delay = 500;
+  try {
+    delay = Services.prefs.getIntPref('ui.click_hold_context_menus.delay');
+  } catch(e) {}
+
+  let TouchEventHandler = {
+    enabled: false,
+    events: ['mousedown', 'mousemove', 'mouseup', 'click'],
+    start: function teh_start() {
+      let isReloadNeeded = Services.prefs.getIntPref('dom.w3c_touch_events.enabled') != 1;
+      handlerCount++;
+      Services.prefs.setIntPref('dom.w3c_touch_events.enabled', 1);
+      this.enabled = true;
+      this.events.forEach((function(evt) {
+        window.addEventListener(evt, this, true);
+      }).bind(this));
+      return isReloadNeeded;
+    },
+    stop: function teh_stop() {
+      handlerCount--;
+      if (handlerCount == 0)
+        Services.prefs.setIntPref('dom.w3c_touch_events.enabled', orig_w3c_touch_events);
+      this.enabled = false;
+      this.events.forEach((function(evt) {
+        window.removeEventListener(evt, this, true);
+      }).bind(this));
+    },
+    handleEvent: function teh_handleEvent(evt) {
+      if (evt.button || ignoreEvents ||
+          evt.mozInputSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN)
+        return;
+
+      // The gaia system window use an hybrid system even on the device which is
+      // a mix of mouse/touch events. So let's not cancel *all* mouse events
+      // if it is the current target.
+      let content = evt.target.ownerDocument.defaultView;
+      let isSystemWindow = content.location.toString().indexOf("system.gaiamobile.org") != -1;
+
+      let eventTarget = this.target;
+      let type = '';
+      switch (evt.type) {
+        case 'mousedown':
+          this.target = evt.target;
+
+          contextMenuTimeout =
+            this.sendContextMenu(evt.target, evt.pageX, evt.pageY, delay);
+
+          this.cancelClick = false;
+          this.startX = evt.pageX;
+          this.startY = evt.pageY;
+
+          // Capture events so if a different window show up the events
+          // won't be dispatched to something else.
+          evt.target.setCapture(false);
+
+          type = 'touchstart';
+          break;
+
+        case 'mousemove':
+          if (!eventTarget)
+            return;
+
+          if (!this.cancelClick) {
+            if (Math.abs(this.startX - evt.pageX) > threshold ||
+                Math.abs(this.startY - evt.pageY) > threshold) {
+              this.cancelClick = true;
+              content.clearTimeout(contextMenuTimeout);
+            }
+          }
+
+          type = 'touchmove';
+          break;
+
+        case 'mouseup':
+          if (!eventTarget)
+            return;
+          this.target = null;
+
+          content.clearTimeout(contextMenuTimeout);
+          type = 'touchend';
+          break;
+
+        case 'click':
+          // Mouse events has been cancelled so dispatch a sequence
+          // of events to where touchend has been fired
+          evt.preventDefault();
+          evt.stopImmediatePropagation();
+
+          if (this.cancelClick)
+            return;
+
+          ignoreEvents = true;
+          content.setTimeout(function dispatchMouseEvents(self) {
+            self.fireMouseEvent('mousedown', evt);
+            self.fireMouseEvent('mousemove', evt);
+            self.fireMouseEvent('mouseup', evt);
+            ignoreEvents = false;
+         }, 0, this);
+
+          return;
+      }
+
+      let target = eventTarget || this.target;
+      if (target && type) {
+        this.sendTouchEvent(evt, target, type);
+      }
+
+      if (!isSystemWindow) {
+        evt.preventDefault();
+        evt.stopImmediatePropagation();
+      }
+    },
+    fireMouseEvent: function teh_fireMouseEvent(type, evt)  {
+      let content = evt.target.ownerDocument.defaultView;
+      var utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
+                         .getInterface(Ci.nsIDOMWindowUtils);
+      utils.sendMouseEvent(type, evt.clientX, evt.clientY, 0, 1, 0, true);
+    },
+    sendContextMenu: function teh_sendContextMenu(target, x, y, delay) {
+      let doc = target.ownerDocument;
+      let evt = doc.createEvent('MouseEvent');
+      evt.initMouseEvent('contextmenu', true, true, doc.defaultView,
+                         0, x, y, x, y, false, false, false, false,
+                         0, null);
+
+      let content = target.ownerDocument.defaultView;
+      let timeout = content.setTimeout((function contextMenu() {
+        target.dispatchEvent(evt);
+        this.cancelClick = true;
+      }).bind(this), delay);
+
+      return timeout;
+    },
+    sendTouchEvent: function teh_sendTouchEvent(evt, target, name) {
+      let document = target.ownerDocument;
+      let content = document.defaultView;
+
+      let touchEvent = document.createEvent('touchevent');
+      let point = document.createTouch(content, target, 0,
+                                       evt.pageX, evt.pageY,
+                                       evt.screenX, evt.screenY,
+                                       evt.clientX, evt.clientY,
+                                       1, 1, 0, 0);
+      let touches = document.createTouchList(point);
+      let targetTouches = touches;
+      let changedTouches = touches;
+      touchEvent.initTouchEvent(name, true, true, content, 0,
+                                false, false, false, false,
+                                touches, targetTouches, changedTouches);
+      target.dispatchEvent(touchEvent);
+      return touchEvent;
+    }
+  };
+
+  return TouchEventHandler;
+}
+
+exports.TouchEventHandler = TouchEventHandler;