Skip to content

Commit

Permalink
Disable tap gesture when track gesture is firing for ancestor node
Browse files Browse the repository at this point in the history
Move tap disable into track start

Fixes #3405
  • Loading branch information
dfreedm committed Feb 11, 2016
1 parent 4411031 commit 6f2c1fc
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 41 deletions.
20 changes: 12 additions & 8 deletions src/standard/gestures.html
Expand Up @@ -230,7 +230,8 @@
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;
// ignore syntethic mouse events after a touch
ignoreMouse(true);
Expand All @@ -247,10 +248,8 @@
for (var i = 0, r; i < recognizers.length; i++) {
r = recognizers[i];
if (gs[r.name] && !handled[r.name]) {
if (r.flow && r.flow.start.indexOf(ev.type) > -1) {
if (r.reset) {
r.reset();
}
if (r.flow && r.flow.start.indexOf(ev.type) > -1 && r.reset) {
r.reset();
}
}
}
Expand Down Expand Up @@ -525,6 +524,10 @@
if (self.hasMovedEnough(x, y)) {
// first move is 'start', subsequent moves are 'move', mouseup is 'end'
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});
if (!hasLeftMouseButton(e)) {
// always fire "end"
Expand All @@ -537,7 +540,6 @@
};
var upfn = function upfn(e) {
if (self.info.started) {
Gestures.prevent('tap');
movefn(e);
}

Expand All @@ -561,6 +563,10 @@
var ct = e.changedTouches[0];
var x = ct.clientX, y = ct.clientY;
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.fire(t, ct);
this.info.state = 'track';
Expand All @@ -573,8 +579,6 @@
var ct = e.changedTouches[0];
// only trackend if track was started and not aborted
if (this.info.started) {
// iff tracking, always prevent tap
Gestures.prevent('tap');
// reset started state on up
this.info.state = 'end';
this.info.addMove({x: ct.clientX, y: ct.clientY});
Expand Down
91 changes: 66 additions & 25 deletions test/unit/gestures-elements.html
Expand Up @@ -94,6 +94,22 @@
</script>
</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">
<script>
Polymer({
Expand All @@ -103,13 +119,8 @@
'tap': 'handle',
'track': 'handle'
},
behaviors: [EventCaptureBehavior],
is: 'x-prevent',
created: function() {
this.stream = [];
},
handle: function(e) {
this.stream.push(e);
},
prevent: function(e, detail) {
detail.prevent('tap');
detail.prevent('track');
Expand All @@ -130,12 +141,7 @@
'tap': 'handle',
'track': 'handle'
},
created: function() {
this.stream = [];
},
handle: function(e) {
this.stream.push(e);
}
behaviors: [EventCaptureBehavior]
});
</script>
</dom-module>
Expand All @@ -144,23 +150,58 @@
<script>
Polymer({
is: 'x-document-listener',
properties: {
stream: {
type: Array,
value: function() {
return [];
}
}
},
setup: function() {
this.listen(document, 'down', 'handler');
this.listen(document, 'down', 'handle');
},
teardown: function() {
this.unlisten(document, 'down', 'handler');
this.unlisten(document, 'down', 'handle');
},
handler: function(e) {
this.stream.push(e);
}
behaviors: [EventCaptureBehavior]
});
</script>
</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>
62 changes: 54 additions & 8 deletions test/unit/gestures.html
Expand Up @@ -81,11 +81,11 @@
assert.equal(obj.mousedown.downup, 2, 'mousedown downup');
assert.equal(obj.mousedown.track, 1, 'mousedown track');
assert.equal(obj.mousedown.tap, 1, 'mousedown tap');
assert.equal(obj.mousedown._count, 4, 'total mousedown')
assert.equal(obj.mousedown._count, 4, 'total mousedown');
assert.equal(obj.touchstart.downup, 2, 'touchstart downup');
assert.equal(obj.touchstart.tap, 1, 'touchstart tap');
assert.equal(obj.touchstart.track, 1, 'touchstart track');
assert.equal(obj.touchstart._count, 4, 'total touchstart')
assert.equal(obj.touchstart._count, 4, 'total touchstart');
assert.equal(obj.touchmove.track, 1, 'touchmove track');
assert.equal(obj.touchmove._count, 1, 'total touchmove');
assert.equal(obj.touchend.downup, 2, 'touchend downup');
Expand All @@ -100,17 +100,17 @@
assert.equal(obj.mousedown.downup, 2, 'mousedown downup');
assert.equal(obj.mousedown.track, 1, 'mousedown track');
assert.equal(obj.mousedown.tap, 1, 'mousedown tap');
assert.equal(obj.mousedown._count, 4, 'total mousedown')
assert.equal(obj.mousedown._count, 4, 'total mousedown');
assert.equal(obj.touchstart.downup, 2, 'touchstart downup');
assert.equal(obj.touchstart.tap, 1, 'touchstart tap');
assert.equal(obj.touchstart.track, 1, 'touchstart track');
assert.equal(obj.touchstart._count, 4, 'total touchstart')
assert.equal(obj.touchstart._count, 4, 'total touchstart');
assert.equal(obj.touchmove.track, 1, 'touchmove track');
assert.equal(obj.touchmove._count, 1, 'total touchmove');
assert.equal(obj.touchend.downup, 2, 'touchend downup');
assert.equal(obj.touchend.track, 1, 'touchend track');
assert.equal(obj.touchend.tap, 1, 'touchend tap');
assert.equal(obj.touchend._count, 4, 'total touchend');;
assert.equal(obj.touchend._count, 4, 'total touchend');
});

test('dynamic', function() {
Expand Down Expand Up @@ -142,7 +142,7 @@
assert.equal(obj.touchstart.downup, 0, 'touchstart downup');
assert.equal(obj.touchstart._count, 0, 'total touchstart');
assert.equal(obj.touchmove.track, 0, 'touchmove track');
assert.equal(obj.touchmove._count, 0, 'total touchmove')
assert.equal(obj.touchmove._count, 0, 'total touchmove');
assert.equal(obj.touchstart.tap, 0, 'touchstart tap');
assert.equal(obj.touchend.downup, 0, 'touchend downup');
assert.equal(obj.touchend.track, 0, 'touchend track');
Expand All @@ -164,7 +164,7 @@
assert.equal(obj.touchstart.downup, 0, 'touchstart downup');
assert.equal(obj.touchstart._count, 0, 'total touchstart');
assert.equal(obj.touchmove.track, 0, 'touchmove track');
assert.equal(obj.touchmove._count, 0, 'total touchmove')
assert.equal(obj.touchmove._count, 0, 'total touchmove');
assert.equal(obj.touchstart.tap, 0, 'touchstart tap');
assert.equal(obj.touchend.downup, 0, 'touchend downup');
assert.equal(obj.touchend.track, 0, 'touchend track');
Expand Down Expand Up @@ -202,7 +202,7 @@
test('target finding returns null outside the window', function() {
var actual = Polymer.Gestures.deepTargetFind(-1, -1);
assert.equal(actual, null);
})
});

test('find the div in document', function() {
var x = divLocation.left, y = divLocation.top;
Expand Down Expand Up @@ -291,6 +291,52 @@
assert.equal(el.stream[0].defaultPrevented, true, 'down was prevented');
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() {
Expand Down

0 comments on commit 6f2c1fc

Please sign in to comment.