diff --git a/lib/utils/gestures.html b/lib/utils/gestures.html index 451433a639..ea2e29c4be 100644 --- a/lib/utils/gestures.html +++ b/lib/utils/gestures.html @@ -40,22 +40,44 @@ } })(); + /** + * @param {string} name Possible mouse event name + * @return {boolean} true if mouse event, false if not + */ + function isMouseEvent(name) { + return MOUSE_EVENTS.indexOf(name) > -1; + } + /* eslint no-empty: ["error", { "allowEmptyCatch": true }] */ // check for passive event listeners let SUPPORTS_PASSIVE = false; (function() { try { - let opts = Object.defineProperty({}, 'passive', {get: function() {SUPPORTS_PASSIVE = true;}}); + let opts = Object.defineProperty({}, 'passive', {get() {SUPPORTS_PASSIVE = true;}}); window.addEventListener('test', null, opts); window.removeEventListener('test', null, opts); } catch(e) {} })(); + /** + * Generate settings for event listeners, dependant on `Polymer.passiveTouchGestures` + * + * @return {{passive: boolean} | undefined} Options to use for addEventListener and removeEventListener + */ + function PASSIVE_TOUCH() { + if (HAS_NATIVE_TA && SUPPORTS_PASSIVE && Polymer.passiveTouchGestures) { + return {passive: true}; + } else { + return; + } + } + // Check for touch-only devices let IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/); let GestureRecognizer = function(){}; // eslint-disable-line no-unused-vars - GestureRecognizer.prototype.reset = function(){}; + /** @type {function()} */ + GestureRecognizer.prototype.reset; /** @type {function(MouseEvent) | undefined} */ GestureRecognizer.prototype.mousedown; /** @type {(function(MouseEvent) | undefined)} */ @@ -140,7 +162,7 @@ function hasLeftMouseButton(ev) { let type = ev.type; // exit early if the event is not a mouse event - if (MOUSE_EVENTS.indexOf(type) === -1) { + if (!isMouseEvent(type)) { return false; } // ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons) @@ -450,7 +472,7 @@ for (let i = 0, dep, gd; i < deps.length; i++) { dep = deps[i]; // don't add mouse handlers on iOS because they cause gray selection overlays - if (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1 && dep !== 'click') { + if (IS_TOUCH_ONLY && isMouseEvent(dep) && dep !== 'click') { continue; } gd = gobj[dep]; @@ -458,7 +480,8 @@ gobj[dep] = gd = {_count: 0}; } if (gd._count === 0) { - node.addEventListener(dep, this._handleNative); + let options = !isMouseEvent(dep) && PASSIVE_TOUCH(); + node.addEventListener(dep, this._handleNative, options); } gd[name] = (gd[name] || 0) + 1; gd._count = (gd._count || 0) + 1; @@ -491,7 +514,8 @@ gd[name] = (gd[name] || 1) - 1; gd._count = (gd._count || 1) - 1; if (gd._count === 0) { - node.removeEventListener(dep, this._handleNative); + let options = !isMouseEvent(dep) && PASSIVE_TOUCH(); + node.removeEventListener(dep, this._handleNative, options); } } } diff --git a/lib/utils/settings.html b/lib/utils/settings.html index 4846ef5334..7d5163e848 100644 --- a/lib/utils/settings.html +++ b/lib/utils/settings.html @@ -93,5 +93,27 @@ Polymer.setSanitizeDOMValue = function(newSanitizeDOMValue) { Polymer.sanitizeDOMValue = newSanitizeDOMValue; }; + + /** + * Globally settable property to make Polymer Gestures use passive TouchEvent listeners when recognizing gestures. + * When set to `true`, gestures made from touch will not be able to prevent scrolling, allowing for smoother + * scrolling performance. + * Defaults to `false` for backwards compatibility. + * + * @memberof Polymer + */ + let passiveTouchGestures = false; + + Polymer.passiveTouchGestures = passiveTouchGestures; + + /** + * Sets `passiveTouchGestures` globally for all elements using Polymer Gestures. + * + * @memberof Polymer + * @param {boolean} usePassive enable or disable passive touch gestures globally + */ + Polymer.setPassiveTouchGestures = function(usePassive) { + Polymer.passiveTouchGestures = usePassive; + }; })(); diff --git a/test/smoke/passive-gestures.html b/test/smoke/passive-gestures.html new file mode 100644 index 0000000000..90e7a9363c --- /dev/null +++ b/test/smoke/passive-gestures.html @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file