Skip to content

Commit 4a2d427

Browse files
author
Steve Orvell
authored
Merge pull request #4829 from Polymer/optional-passive-gestures
App-level support for passive gesture touch listeners
2 parents 5ab0a86 + 3547fd3 commit 4a2d427

File tree

3 files changed

+105
-6
lines changed

3 files changed

+105
-6
lines changed

lib/utils/gestures.html

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,44 @@
4040
}
4141
})();
4242

43+
/**
44+
* @param {string} name Possible mouse event name
45+
* @return {boolean} true if mouse event, false if not
46+
*/
47+
function isMouseEvent(name) {
48+
return MOUSE_EVENTS.indexOf(name) > -1;
49+
}
50+
4351
/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
4452
// check for passive event listeners
4553
let SUPPORTS_PASSIVE = false;
4654
(function() {
4755
try {
48-
let opts = Object.defineProperty({}, 'passive', {get: function() {SUPPORTS_PASSIVE = true;}});
56+
let opts = Object.defineProperty({}, 'passive', {get() {SUPPORTS_PASSIVE = true;}});
4957
window.addEventListener('test', null, opts);
5058
window.removeEventListener('test', null, opts);
5159
} catch(e) {}
5260
})();
5361

62+
/**
63+
* Generate settings for event listeners, dependant on `Polymer.passiveTouchGestures`
64+
*
65+
* @return {{passive: boolean} | undefined} Options to use for addEventListener and removeEventListener
66+
*/
67+
function PASSIVE_TOUCH() {
68+
if (HAS_NATIVE_TA && SUPPORTS_PASSIVE && Polymer.passiveTouchGestures) {
69+
return {passive: true};
70+
} else {
71+
return;
72+
}
73+
}
74+
5475
// Check for touch-only devices
5576
let IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
5677

5778
let GestureRecognizer = function(){}; // eslint-disable-line no-unused-vars
58-
GestureRecognizer.prototype.reset = function(){};
79+
/** @type {function()} */
80+
GestureRecognizer.prototype.reset;
5981
/** @type {function(MouseEvent) | undefined} */
6082
GestureRecognizer.prototype.mousedown;
6183
/** @type {(function(MouseEvent) | undefined)} */
@@ -140,7 +162,7 @@
140162
function hasLeftMouseButton(ev) {
141163
let type = ev.type;
142164
// exit early if the event is not a mouse event
143-
if (MOUSE_EVENTS.indexOf(type) === -1) {
165+
if (!isMouseEvent(type)) {
144166
return false;
145167
}
146168
// ev.button is not reliable for mousemove (0 is overloaded as both left button and no buttons)
@@ -450,15 +472,16 @@
450472
for (let i = 0, dep, gd; i < deps.length; i++) {
451473
dep = deps[i];
452474
// don't add mouse handlers on iOS because they cause gray selection overlays
453-
if (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1 && dep !== 'click') {
475+
if (IS_TOUCH_ONLY && isMouseEvent(dep) && dep !== 'click') {
454476
continue;
455477
}
456478
gd = gobj[dep];
457479
if (!gd) {
458480
gobj[dep] = gd = {_count: 0};
459481
}
460482
if (gd._count === 0) {
461-
node.addEventListener(dep, this._handleNative);
483+
let options = !isMouseEvent(dep) && PASSIVE_TOUCH();
484+
node.addEventListener(dep, this._handleNative, options);
462485
}
463486
gd[name] = (gd[name] || 0) + 1;
464487
gd._count = (gd._count || 0) + 1;
@@ -491,7 +514,8 @@
491514
gd[name] = (gd[name] || 1) - 1;
492515
gd._count = (gd._count || 1) - 1;
493516
if (gd._count === 0) {
494-
node.removeEventListener(dep, this._handleNative);
517+
let options = !isMouseEvent(dep) && PASSIVE_TOUCH();
518+
node.removeEventListener(dep, this._handleNative, options);
495519
}
496520
}
497521
}

lib/utils/settings.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,27 @@
9393
Polymer.setSanitizeDOMValue = function(newSanitizeDOMValue) {
9494
Polymer.sanitizeDOMValue = newSanitizeDOMValue;
9595
};
96+
97+
/**
98+
* Globally settable property to make Polymer Gestures use passive TouchEvent listeners when recognizing gestures.
99+
* When set to `true`, gestures made from touch will not be able to prevent scrolling, allowing for smoother
100+
* scrolling performance.
101+
* Defaults to `false` for backwards compatibility.
102+
*
103+
* @memberof Polymer
104+
*/
105+
let passiveTouchGestures = false;
106+
107+
Polymer.passiveTouchGestures = passiveTouchGestures;
108+
109+
/**
110+
* Sets `passiveTouchGestures` globally for all elements using Polymer Gestures.
111+
*
112+
* @memberof Polymer
113+
* @param {boolean} usePassive enable or disable passive touch gestures globally
114+
*/
115+
Polymer.setPassiveTouchGestures = function(usePassive) {
116+
Polymer.passiveTouchGestures = usePassive;
117+
};
96118
})();
97119
</script>

test/smoke/passive-gestures.html

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!doctype html>
2+
<!--
3+
@license
4+
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
5+
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
6+
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
7+
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
8+
Code distributed by Google as part of the polymer project is also
9+
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
10+
-->
11+
<html>
12+
<head>
13+
<script src="../../../webcomponentsjs/webcomponents-loader.js"></script>
14+
<link rel="import" href="../../polymer.html">
15+
<script>Polymer.setPassiveTouchGestures(true);</script>
16+
<style>
17+
html, body {
18+
margin: 0;
19+
padding: 0;
20+
}
21+
</style>
22+
</head>
23+
<body>
24+
<dom-module id="x-passive">
25+
<template>
26+
<style>
27+
:host {
28+
display: block;
29+
height: 2000px;
30+
background-color: -webkit-gradient(linear, left top, left bottom, from(blue), to(red));
31+
background-image: -webkit-linear-gradient(top, blue, red);
32+
background-image: -moz-linear-gradient(top, blue, red);
33+
background-image: linear-gradient(to bottom, blue, red);
34+
}
35+
</style>
36+
</template>
37+
</dom-module>
38+
<script>
39+
Polymer({
40+
is: 'x-passive',
41+
listeners: {
42+
'down': 'prevent',
43+
'move': 'prevent'
44+
},
45+
prevent(e) {
46+
e.preventDefault();
47+
console.log('prevented!');
48+
}
49+
});
50+
</script>
51+
<x-passive></x-passive>
52+
</body>
53+
</html>

0 commit comments

Comments
 (0)