History

Update FastClick

Thibaut committed 12 years ago

Commit 791de071 parent 97c101b1 file · +62 −14Browse files

Showing the changes to assets/javascripts (1 of 1 file). Show all

Unified · Split

assets/javascripts/vendor/fastclick.js+62−14
@@ -1,7 +1,7 @@
1/**1/**
2 * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.2 * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
3 *3 *
4 * @version 0.6.94 * @version 0.6.11
5 * @codingstandard ftlabs-jsv25 * @codingstandard ftlabs-jsv2
6 * @copyright The Financial Times Limited [All Rights Reserved]6 * @copyright The Financial Times Limited [All Rights Reserved]
7 * @license MIT License (see LICENSE.txt)7 * @license MIT License (see LICENSE.txt)
@@ -98,6 +98,9 @@ function FastClick(layer) { · 90 unmodified lines
98 /** @type function() */98 /** @type function() */
99 this.onTouchStart = function() { return FastClick.prototype.onTouchStart.apply(self, arguments); };99 this.onTouchStart = function() { return FastClick.prototype.onTouchStart.apply(self, arguments); };
100 100
101 /** @type function() */
102 this.onTouchMove = function() { return FastClick.prototype.onTouchMove.apply(self, arguments); };
103
101 /** @type function() */104 /** @type function() */
102 this.onTouchEnd = function() { return FastClick.prototype.onTouchEnd.apply(self, arguments); };105 this.onTouchEnd = function() { return FastClick.prototype.onTouchEnd.apply(self, arguments); };
103 106
@@ -117,6 +120,7 @@ function FastClick(layer) { · 13 unmodified lines
117 120
118 layer.addEventListener('click', this.onClick, true);121 layer.addEventListener('click', this.onClick, true);
119 layer.addEventListener('touchstart', this.onTouchStart, false);122 layer.addEventListener('touchstart', this.onTouchStart, false);
123 layer.addEventListener('touchmove', this.onTouchMove, false);
120 layer.addEventListener('touchend', this.onTouchEnd, false);124 layer.addEventListener('touchend', this.onTouchEnd, false);
121 layer.addEventListener('touchcancel', this.onTouchCancel, false);125 layer.addEventListener('touchcancel', this.onTouchCancel, false);
122 126
@@ -241,8 +245,9 @@ FastClick.prototype.needsFocus = function(target) { · 118 unmodified lines
241 'use strict';245 'use strict';
242 switch (target.nodeName.toLowerCase()) {246 switch (target.nodeName.toLowerCase()) {
243 case 'textarea':247 case 'textarea':
244 case 'select':
245 return true;248 return true;
249 case 'select':
250 return !this.deviceIsAndroid;
246 case 'input':251 case 'input':
247 switch (target.type) {252 switch (target.type) {
248 case 'button':253 case 'button':
@@ -281,11 +286,22 @@ FastClick.prototype.sendClick = function(targetElement, event) { · 32 unmodified lines
281 286
282 // Synthesise a click event, with an extra attribute so it can be tracked287 // Synthesise a click event, with an extra attribute so it can be tracked
283 clickEvent = document.createEvent('MouseEvents');288 clickEvent = document.createEvent('MouseEvents');
284 clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);289 clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
285 clickEvent.forwardedTouchEvent = true;290 clickEvent.forwardedTouchEvent = true;
286 targetElement.dispatchEvent(clickEvent);291 targetElement.dispatchEvent(clickEvent);
287};292};
288 293
294FastClick.prototype.determineEventType = function(targetElement) {
295 'use strict';
296
297 //Issue #159: Android Chrome Select Box does not open with a synthetic click event
298 if (this.deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
299 return 'mousedown';
300 }
301
302 return 'click';
303};
304
289 305
290/**306/**
291 * @param {EventTarget|Element} targetElement307 * @param {EventTarget|Element} targetElement
@@ -294,7 +310,8 @@ FastClick.prototype.focus = function(targetElement) { · 2 unmodified lines
294 'use strict';310 'use strict';
295 var length;311 var length;
296 312
297 if (this.deviceIsIOS && targetElement.setSelectionRange) {313 // Issue #160: on iOS 7, some input elements (e.g. date datetime) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
314 if (this.deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time') {
298 length = targetElement.value.length;315 length = targetElement.value.length;
299 targetElement.setSelectionRange(length, length);316 targetElement.setSelectionRange(length, length);
300 } else {317 } else {
@@ -436,6 +453,28 @@ FastClick.prototype.touchHasMoved = function(event) { · 135 unmodified lines
436};453};
437 454
438 455
456/**
457 * Update the last position.
458 *
459 * @param {Event} event
460 * @returns {boolean}
461 */
462FastClick.prototype.onTouchMove = function(event) {
463 'use strict';
464 if (!this.trackingClick) {
465 return true;
466 }
467
468 // If the touch has moved, cancel the click tracking
469 if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
470 this.trackingClick = false;
471 this.targetElement = null;
472 }
473
474 return true;
475};
476
477
439/**478/**
440 * Attempt to find the labelled control for the given label element.479 * Attempt to find the labelled control for the given label element.
441 *480 *
@@ -471,12 +510,6 @@ FastClick.prototype.onTouchEnd = function(event) { · 29 unmodified lines
471 'use strict';510 'use strict';
472 var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;511 var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
473 512
474 // If the touch has moved, cancel the click tracking
475 if (this.touchHasMoved(event)) {
476 this.trackingClick = false;
477 this.targetElement = null;
478 }
479
480 if (!this.trackingClick) {513 if (!this.trackingClick) {
481 return true;514 return true;
482 }515 }
@@ -487,6 +520,9 @@ FastClick.prototype.onTouchEnd = function(event) { · 4 unmodified lines
487 return true;520 return true;
488 }521 }
489 522
523 // Reset to prevent wrong click cancel on input (issue #156).
524 this.cancelNextClick = false;
525
490 this.lastClickTime = event.timeStamp;526 this.lastClickTime = event.timeStamp;
491 527
492 trackingClickStart = this.trackingClickStart;528 trackingClickStart = this.trackingClickStart;
@@ -671,6 +707,7 @@ FastClick.prototype.destroy = function() { · 178 unmodified lines
671 707
672 layer.removeEventListener('click', this.onClick, true);708 layer.removeEventListener('click', this.onClick, true);
673 layer.removeEventListener('touchstart', this.onTouchStart, false);709 layer.removeEventListener('touchstart', this.onTouchStart, false);
710 layer.removeEventListener('touchmove', this.onTouchMove, false);
674 layer.removeEventListener('touchend', this.onTouchEnd, false);711 layer.removeEventListener('touchend', this.onTouchEnd, false);
675 layer.removeEventListener('touchcancel', this.onTouchCancel, false);712 layer.removeEventListener('touchcancel', this.onTouchCancel, false);
676};713};
@@ -684,19 +721,30 @@ FastClick.prototype.destroy = function() { · 7 unmodified lines
684FastClick.notNeeded = function(layer) {721FastClick.notNeeded = function(layer) {
685 'use strict';722 'use strict';
686 var metaViewport;723 var metaViewport;
724 var chromeVersion;
687 725
688 // Devices that don't support touch don't need FastClick726 // Devices that don't support touch don't need FastClick
689 if (typeof window.ontouchstart === 'undefined') {727 if (typeof window.ontouchstart === 'undefined') {
690 return true;728 return true;
691 }729 }
692 730
693 if ((/Chrome\/[0-9]+/).test(navigator.userAgent)) {731 // Chrome version - zero for other browsers
732 chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
733
734 if (chromeVersion) {
694 735
695 // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
696 if (FastClick.prototype.deviceIsAndroid) {736 if (FastClick.prototype.deviceIsAndroid) {
697 metaViewport = document.querySelector('meta[name=viewport]');737 metaViewport = document.querySelector('meta[name=viewport]');
698 if (metaViewport && metaViewport.content.indexOf('user-scalable=no') !== -1) {738
699 return true;739 if (metaViewport) {
740 // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
741 if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
742 return true;
743 }
744 // Chrome 32 and above with width=device-width or less don't need FastClick
745 if (chromeVersion > 31 && window.innerWidth <= window.screen.width) {
746 return true;
747 }
700 }748 }
701 749
702 // Chrome desktop doesn't need FastClick (issue #15)750 // Chrome desktop doesn't need FastClick (issue #15)