Skip to content

Commit

Permalink
Merge pull request #4131 from Polymer/fix-ghostclick-nogesture
Browse files Browse the repository at this point in the history
Use document-wide passive touch listener to update ghostclick blocker
  • Loading branch information
dfreedm authored Nov 4, 2016
2 parents 77f8a69 + 5ddcb8d commit 37eef0e
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/standard/gestures.html
Original file line number Diff line number Diff line change
Expand Up @@ -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/);

Expand Down Expand Up @@ -82,7 +93,7 @@
}
}

function ignoreMouse() {
function ignoreMouse(ev) {
if (!POINTERSTATE.mouse.mouseIgnoreJob) {
setupTeardownMouseCanceller(true);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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: [],
Expand Down Expand Up @@ -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];
Expand Down
14 changes: 14 additions & 0 deletions test/unit/gestures-elements.html
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,17 @@
});
</script>
</dom-module>

<dom-module id="x-no-gesture">
<template>
<button id="one" on-click="handle" on-down="noop">One</button>
<button id="two" on-click="handle">Two</button>
</template>
<script>
Polymer({
is: 'x-no-gesture',
behaviors: [EventCaptureBehavior],
noop: function(){}
})
</script>
</dom-module>
37 changes: 37 additions & 0 deletions test/unit/gestures.html
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
});
</script>

Expand Down

0 comments on commit 37eef0e

Please sign in to comment.