/*global Application */ /** * Tap highlight behavior for elements and elements in lists. * Copied from //webclient/... Adjusted slightly. */ ;(function($) { /** * Set event type based on browser support of touch events. * The desktop browsers, and mobile IE do not support touch events. */ var touch = ("ontouchstart" in document.body); $.touchEvents = { start: (touch) ? "touchstart" : "mousedown", move: (touch) ? "touchmove" : "mousemove", end: (touch) ? "touchend" : "mouseup mouseout", endOnly: (touch) ? "touchend touchcancel" : "mouseup", cancel: (touch) ? "touchend touchcancel touchmove" : "mouseup mousemove mouseout", getTarget: function(e) { return touch ? $(e.originalEvent.touches[0].target) : $(e.target); } // , // getCoord: function(e) { // // e.originalEvent is necessary because you are using jQuery. // return touch ? // {x: e.originalEvent.touches[0].pageX, y: e.originalEvent.touches[0].pageY} : // {x: e.pageX, y: e.pageY}; // } }; /** * Highlight a single element * * Finds elements with .hhl, adds .hl when active. */ ;(function() { var SELECTOR = '.hhl'; var CSS_CLASS = 'hl'; $(document.body) .on($.touchEvents.start, SELECTOR, function() { $(this).closest(SELECTOR).addClass(CSS_CLASS); }) .on($.touchEvents.cancel, SELECTOR, function() { $(this).closest(SELECTOR).removeClass(CSS_CLASS); }); })(); /** * Highlight elements in a list. */ $.fn.list_hl = function(selector, func) { var $this = this, HL = "hl", $el = null, timer = null; var endEvent = window.location.search.indexOf('client=ios') !== -1 ? $.touchEvents.endOnly : 'click'; $(selector).removeClass(HL); $this .off($.touchEvents.start, selector) .off($.touchEvents.move, selector) .off($.touchEvents.endOnly, selector) .on($.touchEvents.start, selector, start) .on($.touchEvents.move, selector, clear) .on(endEvent, selector, end); function hl() { $el.addClass(HL); } function start(e) { // Do not proceed if another element is // set. Wait until clear() runs. if ($el) return; $el = $.touchEvents.getTarget(e).closest(selector); if (Application.client.ios) { timer = setTimeout(hl, 90); } } function clear() { if (!$el) return; $el.removeClass(HL); $el = null; if (timer) { clearTimeout(timer); timer = null; } } // iOS: runs on `touchend` and `touchcancel` // Android: runs on `click` // // If you use "touchend" as the last event for Android // it will fire a click event even if you run e.preventDefault() // This click event will then likely fire on the next view, and // it will inadvertanly navigate or click a tab, etc. // By using "click", there are no more events to run, so it // can't fuck up. // Note this issue is more common, or maybe only present, on // Android OS v2.x. // And on iOS, if you try to use the click event as the last event // nothing happens, and it works and is faster to use touchend. function end(e) { if (!$el) return; hl(); e.preventDefault(); if (Application.client.ios) { func(e, $el); setTimeout(clear, 400); } if (Application.client.android) { setTimeout(function() { func(e, $el); clear(); }, 200); } } }; }(Zepto));