diff --git a/src/standard/gestures.html b/src/standard/gestures.html index f5e13ad4ae..63c9a9cdbb 100644 --- a/src/standard/gestures.html +++ b/src/standard/gestures.html @@ -38,6 +38,17 @@ } })(); + /* eslint no-empty: ["error", { "allowEmptyCatch": true }] */ + // check for passive event listeners + var SUPPORTS_PASSIVE = false; + (function() { + try { + var opts = Object.defineProperty({}, 'passive', {get: function() {SUPPORTS_PASSIVE = true;}}) + window.addEventListener('test', null, opts); + window.removeEventListener('test', null, opts); + } catch(e) {} + })(); + // Check for touch-only devices var IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/); @@ -82,7 +93,7 @@ } } - function ignoreMouse() { + function ignoreMouse(ev) { if (!POINTERSTATE.mouse.mouseIgnoreJob) { setupTeardownMouseCanceller(true); } @@ -91,6 +102,7 @@ POINTERSTATE.mouse.target = null; POINTERSTATE.mouse.mouseIgnoreJob = null; }; + POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget; POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT); } @@ -178,6 +190,10 @@ stateObj.upfn = null; } + // use a document-wide touchend listener to start the ghost-click prevention mechanism + // Use passive event listeners, if supported, to not affect scrolling performance + document.addEventListener('touchend', ignoreMouse, SUPPORTS_PASSIVE ? {passive: true} : false); + var Gestures = { gestures: {}, recognizers: [], @@ -236,12 +252,6 @@ Gestures.handleTouchAction(ev); } } - // disable synth mouse events, unless this event is itself simulated - if (type === 'touchend') { - POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget; - // ignore syntethic mouse events after a touch - ignoreMouse(); - } } } handled = ev[HANDLED_OBJ]; diff --git a/test/unit/gestures-elements.html b/test/unit/gestures-elements.html index 93dff59533..1bb4a62fd6 100644 --- a/test/unit/gestures-elements.html +++ b/test/unit/gestures-elements.html @@ -205,3 +205,17 @@ }); + + + + + \ No newline at end of file diff --git a/test/unit/gestures.html b/test/unit/gestures.html index 52f343f1da..5840ded1c5 100644 --- a/test/unit/gestures.html +++ b/test/unit/gestures.html @@ -489,6 +489,43 @@ assert.isNull(r.info.upfn, r.name + ' upfn'); }); }); + + suite('Interop', function() { + teardown(function() { + Polymer.Gestures.resetMouseCanceller(); + }); + function tap(target) { + var options = {bubbles: true, cancelable: true}; + ['touchstart', 'touchmove', 'touchend'].forEach(function(n) { + var ev = new CustomEvent(n, options); + ev.touches = ev.changedTouches = [ + { + clientX: 0, + clientY: 0, + identifier: 1, + target: target + } + ]; + ev.clientX = 0; + ev.clientY = 0; + target.dispatchEvent(ev); + }); + ['mousedown', 'mousemove', 'mouseup', 'click'].forEach(function(n) { + var ev = new CustomEvent(n, options); + ev.button = 0; + ev.buttons = 1; + target.dispatchEvent(ev); + }); + } + test('elements without gestures click reliably', function() { + var el = document.createElement('x-no-gesture'); + document.body.appendChild(el); + CustomElements.takeRecords(); + tap(el.$.one); + tap(el.$.two); + assert.equal(el.stream.length, 2); + }); + }); });