Merge pull request #3407 from Polymer/fix-nested-track-tap

Disable tap gesture when track gesture is firing for ancestor node
This commit is contained in:
Kevin Schaaf 2016-02-16 14:39:31 -08:00
commit fdd49418c3
3 changed files with 124 additions and 33 deletions

View File

@ -230,7 +230,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Gestures.handleTouchAction(ev); Gestures.handleTouchAction(ev);
} }
} }
if (type === 'touchend') { // disable synth mouse events, unless this event is itself simulated
if (type === 'touchend' && !ev.__polymerSimulatedTouch) {
POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget; POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget;
// ignore syntethic mouse events after a touch // ignore syntethic mouse events after a touch
ignoreMouse(true); ignoreMouse(true);
@ -247,10 +248,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
for (var i = 0, r; i < recognizers.length; i++) { for (var i = 0, r; i < recognizers.length; i++) {
r = recognizers[i]; r = recognizers[i];
if (gs[r.name] && !handled[r.name]) { if (gs[r.name] && !handled[r.name]) {
if (r.flow && r.flow.start.indexOf(ev.type) > -1) { if (r.flow && r.flow.start.indexOf(ev.type) > -1 && r.reset) {
if (r.reset) { r.reset();
r.reset();
}
} }
} }
} }
@ -525,6 +524,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
if (self.hasMovedEnough(x, y)) { if (self.hasMovedEnough(x, y)) {
// first move is 'start', subsequent moves are 'move', mouseup is 'end' // first move is 'start', subsequent moves are 'move', mouseup is 'end'
self.info.state = self.info.started ? (e.type === 'mouseup' ? 'end' : 'track') : 'start'; self.info.state = self.info.started ? (e.type === 'mouseup' ? 'end' : 'track') : 'start';
if (self.info.state === 'start') {
// iff tracking, always prevent tap
Gestures.prevent('tap');
}
self.info.addMove({x: x, y: y}); self.info.addMove({x: x, y: y});
if (!hasLeftMouseButton(e)) { if (!hasLeftMouseButton(e)) {
// always fire "end" // always fire "end"
@ -537,7 +540,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}; };
var upfn = function upfn(e) { var upfn = function upfn(e) {
if (self.info.started) { if (self.info.started) {
Gestures.prevent('tap');
movefn(e); movefn(e);
} }
@ -561,6 +563,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var ct = e.changedTouches[0]; var ct = e.changedTouches[0];
var x = ct.clientX, y = ct.clientY; var x = ct.clientX, y = ct.clientY;
if (this.hasMovedEnough(x, y)) { if (this.hasMovedEnough(x, y)) {
if (this.info.state === 'start') {
// iff tracking, always prevent tap
Gestures.prevent('tap');
}
this.info.addMove({x: x, y: y}); this.info.addMove({x: x, y: y});
this.fire(t, ct); this.fire(t, ct);
this.info.state = 'track'; this.info.state = 'track';
@ -573,8 +579,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var ct = e.changedTouches[0]; var ct = e.changedTouches[0];
// only trackend if track was started and not aborted // only trackend if track was started and not aborted
if (this.info.started) { if (this.info.started) {
// iff tracking, always prevent tap
Gestures.prevent('tap');
// reset started state on up // reset started state on up
this.info.state = 'end'; this.info.state = 'end';
this.info.addMove({x: ct.clientX, y: ct.clientY}); this.info.addMove({x: ct.clientX, y: ct.clientY});

View File

@ -94,6 +94,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</script> </script>
</dom-module> </dom-module>
<script>
var EventCaptureBehavior = {
properties: {
stream: {
type: Array,
value: function() {
return [];
}
}
},
handle: function(e) {
this.stream.push(e);
}
};
</script>
<dom-module id="x-prevent"> <dom-module id="x-prevent">
<script> <script>
Polymer({ Polymer({
@ -103,13 +119,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
'tap': 'handle', 'tap': 'handle',
'track': 'handle' 'track': 'handle'
}, },
behaviors: [EventCaptureBehavior],
is: 'x-prevent', is: 'x-prevent',
created: function() {
this.stream = [];
},
handle: function(e) {
this.stream.push(e);
},
prevent: function(e, detail) { prevent: function(e, detail) {
detail.prevent('tap'); detail.prevent('tap');
detail.prevent('track'); detail.prevent('track');
@ -130,12 +141,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
'tap': 'handle', 'tap': 'handle',
'track': 'handle' 'track': 'handle'
}, },
created: function() { behaviors: [EventCaptureBehavior]
this.stream = [];
},
handle: function(e) {
this.stream.push(e);
}
}); });
</script> </script>
</dom-module> </dom-module>
@ -144,23 +150,58 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<script> <script>
Polymer({ Polymer({
is: 'x-document-listener', is: 'x-document-listener',
properties: {
stream: {
type: Array,
value: function() {
return [];
}
}
},
setup: function() { setup: function() {
this.listen(document, 'down', 'handler'); this.listen(document, 'down', 'handle');
}, },
teardown: function() { teardown: function() {
this.unlisten(document, 'down', 'handler'); this.unlisten(document, 'down', 'handle');
}, },
handler: function(e) { behaviors: [EventCaptureBehavior]
this.stream.push(e);
}
}); });
</script> </script>
</dom-module> </dom-module>
<dom-module id="x-nested-child-prevent">
<script>
Polymer({
is: 'x-nested-child-prevent',
listeners: {
tap: 'handle'
},
behaviors: [EventCaptureBehavior]
});
</script>
</dom-module>
<dom-module id="x-nested-prevent">
<template>
<style>
:host {
position: absolute;
display: block;
background: orange;
height: 100px;
width: 100px;
}
#child {
position: relative;
display: block;
background: blue;
height: 50px;
width: 50px;
margin-top: 25px;
margin-left: 25px;
}
</style>
<x-nested-child-prevent id="child"></x-nested-child-prevent>
</template>
<script>
Polymer({
is: 'x-nested-prevent',
listeners: {
track: 'handle'
},
behaviors: [EventCaptureBehavior]
});
</script>
</dom-module>

View File

@ -291,6 +291,52 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.equal(el.stream[0].defaultPrevented, true, 'down was prevented'); assert.equal(el.stream[0].defaultPrevented, true, 'down was prevented');
assert.equal(el.stream[1].type, 'up', 'up was found'); assert.equal(el.stream[1].type, 'up', 'up was found');
}); });
test('nested track and tap with touch', function() {
el.parentNode.removeChild(el);
el = document.createElement('x-nested-prevent');
var child = el.$.child;
document.body.appendChild(el);
var options = {bubbles: true, cancelable: true};
var bgr = el.getBoundingClientRect();
var clientX = bgr.left + (bgr.width / 2);
var clientY = bgr.top + (bgr.bottom / 2);
var ev = new CustomEvent('touchstart', options);
ev.touches = ev.changedTouches = [
{
clientX: clientX,
clientY: clientY,
identifier: 1,
target: child
}
];
ev.clientX = clientX;
ev.clientY = clientY;
ev.__polymerSimulatedTouch = true;
child.dispatchEvent(ev);
for (var i = 0; i < 10; i++) {
clientX += 1;
ev = new CustomEvent(i === 9 ? 'touchend' : 'touchmove', options);
ev.touches = ev.changedTouches = [
{
clientX: clientX,
clientY: clientY,
identifier: 1,
target: child
}
];
ev.clientX = clientX;
ev.clientY = clientY;
// tell gestures to not turn off mouse events
ev.__polymerSimulatedTouch = true;
child.dispatchEvent(ev);
}
assert.equal(child.stream.length, 0, 'expected no taps on the child');
assert.notEqual(el.stream.length, 0, 'expected some tracks on the parent');
});
}); });
suite('Buttons', function() { suite('Buttons', function() {