summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/modern-media-controls/gesture-recognizers/tap.js
diff options
context:
space:
mode:
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.js109
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();
+ }
+
+}