blob: c50e33d38c993bcb134c7ed35b6808afea9f1db3 [file] [log] [blame]
const MOVE_TOLERANCE = GestureRecognizer.SupportsTouches ? 40 : 0;
const WAITING_FOR_NEXT_TAP_TO_START_TIMEOUT = 350;
const WAITING_FOR_TAP_COMPLETION_TIMEOUT = 750;
class TapGestureRecognizer extends GestureRecognizer
{
constructor(target, delegate)
{
super(target, delegate);
this.numberOfTapsRequired = 1;
this.numberOfTouchesRequired = 1;
this.allowsRightMouseButton = false;
}
// Protected
touchesBegan(event)
{
if (event.currentTarget !== this.target)
return;
if (event.button === 2 && !this.allowsRightMouseButton)
return;
super.touchesBegan(event);
if (this.numberOfTouches !== this.numberOfTouchesRequired) {
this.enterFailedState();
return;
}
this._startPoint = super.locationInElement();
this._startClientPoint = super.locationInClient();
this._rewindTimer(WAITING_FOR_TAP_COMPLETION_TIMEOUT);
}
touchesMoved(event)
{
const touchLocation = super.locationInElement();
const distance = Math.sqrt(Math.pow(this._startPoint.x - touchLocation.x, 2) + Math.pow(this._startPoint.y - touchLocation.y, 2));
if (distance > MOVE_TOLERANCE)
this.enterFailedState();
}
touchesEnded(event)
{
this._taps++;
if (this._taps === this.numberOfTapsRequired) {
// We call prevent default here to override the potential double-tap-to-zoom
// behavior of the browser.
event.preventDefault();
this.enterRecognizedState();
this.reset();
}
this._rewindTimer(WAITING_FOR_NEXT_TAP_TO_START_TIMEOUT);
}
reset()
{
this._taps = 0;
this._clearTimer();
}
locationInElement(element)
{
const p = this._startPoint || new DOMPoint;
if (!element)
return p;
// FIXME: are WebKitPoint and DOMPoint interchangeable?
const wkPoint = window.webkitConvertPointFromPageToNode(element, new WebKitPoint(p.x, p.y));
return new DOMPoint(wkPoint.x, wkPoint.y);
}
locationInClient()
{
return this._startClientPoint || new DOMPoint;
}
// Private
_clearTimer()
{
window.clearTimeout(this._timerId);
delete this._timerId;
}
_rewindTimer(timeout)
{
this._clearTimer();
this._timerId = window.setTimeout(this._timerFired.bind(this), timeout);
}
_timerFired()
{
this.enterFailedState();
}
}