accessible/src/jsat/PointerAdapter.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /* global Components, XPCOMUtils, Utils, Logger, GestureSettings,
michael@0 6 GestureTracker */
michael@0 7 /* exported PointerRelay, PointerAdapter */
michael@0 8
michael@0 9 'use strict';
michael@0 10
michael@0 11 const Ci = Components.interfaces;
michael@0 12 const Cu = Components.utils;
michael@0 13
michael@0 14 this.EXPORTED_SYMBOLS = ['PointerRelay', 'PointerAdapter']; // jshint ignore:line
michael@0 15
michael@0 16 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
michael@0 17
michael@0 18 XPCOMUtils.defineLazyModuleGetter(this, 'Utils', // jshint ignore:line
michael@0 19 'resource://gre/modules/accessibility/Utils.jsm');
michael@0 20 XPCOMUtils.defineLazyModuleGetter(this, 'Logger', // jshint ignore:line
michael@0 21 'resource://gre/modules/accessibility/Utils.jsm');
michael@0 22 XPCOMUtils.defineLazyModuleGetter(this, 'GestureSettings', // jshint ignore:line
michael@0 23 'resource://gre/modules/accessibility/Gestures.jsm');
michael@0 24 XPCOMUtils.defineLazyModuleGetter(this, 'GestureTracker', // jshint ignore:line
michael@0 25 'resource://gre/modules/accessibility/Gestures.jsm');
michael@0 26
michael@0 27 // The virtual touch ID generated by a mouse event.
michael@0 28 const MOUSE_ID = 'mouse';
michael@0 29 // Synthesized touch ID.
michael@0 30 const SYNTH_ID = -1;
michael@0 31
michael@0 32 let PointerRelay = { // jshint ignore:line
michael@0 33 /**
michael@0 34 * A mapping of events we should be intercepting. Entries with a value of
michael@0 35 * |true| are used for compiling high-level gesture events. Entries with a
michael@0 36 * value of |false| are cancelled and do not propogate to content.
michael@0 37 */
michael@0 38 get _eventsOfInterest() {
michael@0 39 delete this._eventsOfInterest;
michael@0 40
michael@0 41 switch (Utils.widgetToolkit) {
michael@0 42 case 'gonk':
michael@0 43 this._eventsOfInterest = {
michael@0 44 'touchstart' : true,
michael@0 45 'touchmove' : true,
michael@0 46 'touchend' : true,
michael@0 47 'mousedown' : false,
michael@0 48 'mousemove' : false,
michael@0 49 'mouseup': false,
michael@0 50 'click': false };
michael@0 51 break;
michael@0 52
michael@0 53 case 'android':
michael@0 54 this._eventsOfInterest = {
michael@0 55 'touchstart' : true,
michael@0 56 'touchmove' : true,
michael@0 57 'touchend' : true,
michael@0 58 'mousemove' : true,
michael@0 59 'mouseenter' : true,
michael@0 60 'mouseleave' : true,
michael@0 61 'mousedown' : false,
michael@0 62 'mouseup': false,
michael@0 63 'click': false };
michael@0 64 break;
michael@0 65
michael@0 66 default:
michael@0 67 // Desktop.
michael@0 68 this._eventsOfInterest = {
michael@0 69 'mousemove' : true,
michael@0 70 'mousedown' : true,
michael@0 71 'mouseup': true,
michael@0 72 'click': false
michael@0 73 };
michael@0 74 if ('ontouchstart' in Utils.win) {
michael@0 75 for (let eventType of ['touchstart', 'touchmove', 'touchend']) {
michael@0 76 this._eventsOfInterest[eventType] = true;
michael@0 77 }
michael@0 78 }
michael@0 79 break;
michael@0 80 }
michael@0 81
michael@0 82 return this._eventsOfInterest;
michael@0 83 },
michael@0 84
michael@0 85 _eventMap: {
michael@0 86 'touchstart' : 'pointerdown',
michael@0 87 'mousedown' : 'pointerdown',
michael@0 88 'mouseenter' : 'pointerdown',
michael@0 89 'touchmove' : 'pointermove',
michael@0 90 'mousemove' : 'pointermove',
michael@0 91 'touchend' : 'pointerup',
michael@0 92 'mouseup': 'pointerup',
michael@0 93 'mouseleave': 'pointerup'
michael@0 94 },
michael@0 95
michael@0 96 start: function PointerRelay_start(aOnPointerEvent) {
michael@0 97 Logger.debug('PointerRelay.start');
michael@0 98 this.onPointerEvent = aOnPointerEvent;
michael@0 99 for (let eventType in this._eventsOfInterest) {
michael@0 100 Utils.win.addEventListener(eventType, this, true, true);
michael@0 101 }
michael@0 102 },
michael@0 103
michael@0 104 stop: function PointerRelay_stop() {
michael@0 105 Logger.debug('PointerRelay.stop');
michael@0 106 delete this.lastPointerMove;
michael@0 107 delete this.onPointerEvent;
michael@0 108 for (let eventType in this._eventsOfInterest) {
michael@0 109 Utils.win.removeEventListener(eventType, this, true, true);
michael@0 110 }
michael@0 111 },
michael@0 112
michael@0 113 _suppressPointerMove: function PointerRelay__suppressPointerMove(aChangedTouches) {
michael@0 114 if (!this.lastPointerMove) {
michael@0 115 return false;
michael@0 116 }
michael@0 117 for (let i = 0; i < aChangedTouches.length; ++i) {
michael@0 118 let touch = aChangedTouches[i];
michael@0 119 let lastTouch;
michael@0 120 try {
michael@0 121 lastTouch = this.lastPointerMove.identifiedTouch ?
michael@0 122 this.lastPointerMove.identifiedTouch(touch.identifier) :
michael@0 123 this.lastPointerMove[i];
michael@0 124 } catch (x) {
michael@0 125 // Sometimes touch object can't be accessed after page navigation.
michael@0 126 }
michael@0 127 if (!lastTouch || lastTouch.target !== touch.target ||
michael@0 128 Math.hypot(touch.screenX - lastTouch.screenX, touch.screenY -
michael@0 129 lastTouch.screenY) / Utils.dpi >= GestureSettings.travelThreshold) {
michael@0 130 return false;
michael@0 131 }
michael@0 132 }
michael@0 133 return true;
michael@0 134 },
michael@0 135
michael@0 136 handleEvent: function PointerRelay_handleEvent(aEvent) {
michael@0 137 // Don't bother with chrome mouse events.
michael@0 138 if (Utils.MozBuildApp === 'browser' &&
michael@0 139 aEvent.view.top instanceof Ci.nsIDOMChromeWindow) {
michael@0 140 return;
michael@0 141 }
michael@0 142 if (aEvent.mozInputSource === Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN) {
michael@0 143 // Ignore events that are scripted or clicks from the a11y API.
michael@0 144 return;
michael@0 145 }
michael@0 146
michael@0 147 let changedTouches = aEvent.changedTouches || [{
michael@0 148 identifier: MOUSE_ID,
michael@0 149 screenX: aEvent.screenX,
michael@0 150 screenY: aEvent.screenY,
michael@0 151 target: aEvent.target
michael@0 152 }];
michael@0 153
michael@0 154 if (changedTouches.length === 1 &&
michael@0 155 changedTouches[0].identifier === SYNTH_ID) {
michael@0 156 return;
michael@0 157 }
michael@0 158
michael@0 159 aEvent.preventDefault();
michael@0 160 aEvent.stopImmediatePropagation();
michael@0 161
michael@0 162 let type = aEvent.type;
michael@0 163 if (!this._eventsOfInterest[type]) {
michael@0 164 return;
michael@0 165 }
michael@0 166 let pointerType = this._eventMap[type];
michael@0 167 if (pointerType === 'pointermove') {
michael@0 168 if (this._suppressPointerMove(changedTouches)) {
michael@0 169 // Do not fire pointermove more than every POINTERMOVE_THROTTLE.
michael@0 170 return;
michael@0 171 }
michael@0 172 this.lastPointerMove = changedTouches;
michael@0 173 }
michael@0 174 this.onPointerEvent({
michael@0 175 type: pointerType,
michael@0 176 points: Array.prototype.map.call(changedTouches,
michael@0 177 function mapTouch(aTouch) {
michael@0 178 return {
michael@0 179 identifier: aTouch.identifier,
michael@0 180 x: aTouch.screenX,
michael@0 181 y: aTouch.screenY
michael@0 182 };
michael@0 183 }
michael@0 184 )
michael@0 185 });
michael@0 186 }
michael@0 187 };
michael@0 188
michael@0 189 this.PointerAdapter = { // jshint ignore:line
michael@0 190 start: function PointerAdapter_start() {
michael@0 191 Logger.debug('PointerAdapter.start');
michael@0 192 GestureTracker.reset();
michael@0 193 PointerRelay.start(this.handleEvent);
michael@0 194 },
michael@0 195
michael@0 196 stop: function PointerAdapter_stop() {
michael@0 197 Logger.debug('PointerAdapter.stop');
michael@0 198 PointerRelay.stop();
michael@0 199 GestureTracker.reset();
michael@0 200 },
michael@0 201
michael@0 202 handleEvent: function PointerAdapter_handleEvent(aDetail) {
michael@0 203 let timeStamp = Date.now();
michael@0 204 GestureTracker.handle(aDetail, timeStamp);
michael@0 205 }
michael@0 206 };

mercurial