diff options
Diffstat (limited to 'Source/WebCore/Modules/modern-media-controls/gesture-recognizers/tap.js')
-rw-r--r-- | Source/WebCore/Modules/modern-media-controls/gesture-recognizers/tap.js | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/Source/WebCore/Modules/modern-media-controls/gesture-recognizers/tap.js b/Source/WebCore/Modules/modern-media-controls/gesture-recognizers/tap.js new file mode 100644 index 000000000..6f2dbf885 --- /dev/null +++ b/Source/WebCore/Modules/modern-media-controls/gesture-recognizers/tap.js @@ -0,0 +1,109 @@ + +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) + { + event.preventDefault(); + + 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(); + } + +} |