From cf94612f6b12f46562f5d5a80af4d3a67b688939 Mon Sep 17 00:00:00 2001 From: jerel Date: Fri, 21 Dec 2012 01:54:15 -0600 Subject: [PATCH 1/3] Fixes #1041, Android WebView triggers two clicks at once. This calls L.DomEvent.stop(event) on the second if two clicks are triggered within 400ms of each other. Double click is unaffected however. There are other workarounds that focus on _fireMouseEvent(), however I had to resolve it at the click event level as my map, markers, controls, were all affected. --- src/dom/DomEvent.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/dom/DomEvent.js b/src/dom/DomEvent.js index 6246a7be..c8ea71dd 100644 --- a/src/dom/DomEvent.js +++ b/src/dom/DomEvent.js @@ -41,6 +41,13 @@ L.DomEvent = { obj.addEventListener(newType, handler, false); + } else if (type === 'click') { + originalHandler = handler; + handler = function(e) { + return L.DomEvent._filterClick(e, originalHandler); + }; + + obj.addEventListener(type, handler, false); } else { obj.addEventListener(type, handler, false); } @@ -179,6 +186,21 @@ L.DomEvent = { } } return e; + }, + /*jshint noarg:false */ + + // this solves a bug in Android WebView where + // a single touch triggers two click events. + _filterClick: function(e, handler) { + // are they closer together than 400ms? + // Android typically triggers them ~300ms apart + if ((e.timeStamp - L.DomEvent._lastClick) < 400) { + L.DomEvent.stop(e); + return; + } + L.DomEvent._lastClick = e.timeStamp; + + return handler(e); } }; From 0919b25cd6fba8457940967acfb2f07bb65da761 Mon Sep 17 00:00:00 2001 From: jerel Date: Fri, 21 Dec 2012 08:37:13 -0600 Subject: [PATCH 2/3] This makes sure we only do the Android duplicate click workaround on Android --- src/dom/DomEvent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dom/DomEvent.js b/src/dom/DomEvent.js index c8ea71dd..bf352cc8 100644 --- a/src/dom/DomEvent.js +++ b/src/dom/DomEvent.js @@ -41,7 +41,7 @@ L.DomEvent = { obj.addEventListener(newType, handler, false); - } else if (type === 'click') { + } else if (type === 'click' && L.Browser.android) { originalHandler = handler; handler = function(e) { return L.DomEvent._filterClick(e, originalHandler); From c63e3721cbe4732e50380725cebbe595f85b3d4d Mon Sep 17 00:00:00 2001 From: jerel Date: Thu, 27 Dec 2012 00:40:41 -0600 Subject: [PATCH 3/3] This modifies the Android WebView phantom click workaround. Previously it was blocking when an element had multiple click listeners because those events were fired rapidly. Since Android fires its second click at approximately 300ms after the first we do a check to make sure that at least 100ms has elapsed but not more than 400ms. --- src/dom/DomEvent.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dom/DomEvent.js b/src/dom/DomEvent.js index bf352cc8..3ab42867 100644 --- a/src/dom/DomEvent.js +++ b/src/dom/DomEvent.js @@ -192,9 +192,11 @@ L.DomEvent = { // this solves a bug in Android WebView where // a single touch triggers two click events. _filterClick: function(e, handler) { - // are they closer together than 400ms? - // Android typically triggers them ~300ms apart - if ((e.timeStamp - L.DomEvent._lastClick) < 400) { + var elapsed = (typeof(L.DomEvent._lastClick) === 'undefined') ? null : (e.timeStamp - L.DomEvent._lastClick); + // are they closer together than 400ms yet more than 100ms? + // Android typically triggers them ~300ms apart while multiple listeners + // on the same event should be triggered far faster. + if (elapsed > 100 && elapsed < 400) { L.DomEvent.stop(e); return; }