Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Allow for multiple pointer capturing
Browse files Browse the repository at this point in the history
Fixes #108
  • Loading branch information
dfreedm committed Mar 18, 2014
1 parent ef02daa commit 1fc32b7
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 22 deletions.
24 changes: 10 additions & 14 deletions src/dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
*/
var dispatcher = {
pointermap: new scope.PointerMap(),
eventMap: {},
eventMap: Object.create(null),
captureInfo: Object.create(null),
// Scope objects for native events.
// This exists for ease of testing.
eventSources: Object.create(null),
Expand Down Expand Up @@ -227,7 +228,7 @@
*/
makeEvent: function(inType, inEvent) {
// relatedTarget must be null if pointer is captured
if (this.captureInfo) {
if (this.captureInfo[inEvent.pointerId]) {
inEvent.relatedTarget = null;
}
var e = new PointerEvent(inType, inEvent);
Expand Down Expand Up @@ -274,18 +275,13 @@
getTarget: function(inEvent) {
// if pointer capture is set, route all events for the specified pointerId
// to the capture target
if (this.captureInfo) {
if (this.captureInfo.id === inEvent.pointerId) {
return this.captureInfo.target;
}
}
return inEvent._target;
return this.captureInfo[inEvent.pointerId] || inEvent._target;
},
setCapture: function(inPointerId, inTarget) {
if (this.captureInfo) {
this.releaseCapture(this.captureInfo.id);
if (this.captureInfo[inPointerId]) {
this.releaseCapture(inPointerId);
}
this.captureInfo = {id: inPointerId, target: inTarget};
this.captureInfo[inPointerId] = inTarget;
var e = document.createEvent('Event');
e.initEvent('gotpointercapture', true, false);
e.pointerId = inPointerId;
Expand All @@ -296,12 +292,12 @@
this.asyncDispatchEvent(e);
},
releaseCapture: function(inPointerId) {
if (this.captureInfo && this.captureInfo.id === inPointerId) {
var t = this.captureInfo[inPointerId];
if (t) {
var e = document.createEvent('Event');
e.initEvent('lostpointercapture', true, false);
e.pointerId = inPointerId;
var t = this.captureInfo.target;
this.captureInfo = null;
this.captureInfo[inPointerId] = undefined;
document.removeEventListener('pointerup', this.implicitRelease);
document.removeEventListener('pointercancel', this.implicitRelease);
e._target = t;
Expand Down
7 changes: 3 additions & 4 deletions src/touch.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

(function(scope) {
var dispatcher = scope.dispatcher;
var captureInfo = dispatcher.captureInfo;
var findTarget = scope.findTarget;
var allShadows = scope.targetFinding.allShadows.bind(scope.targetFinding);
var pointermap = dispatcher.pointermap;
Expand Down Expand Up @@ -149,10 +150,8 @@
// Spec specifies that pointerId 1 is reserved for Mouse.
// Touch identifiers can start at 0.
// Add 2 to the touch identifier for compatibility.
var pi = e.pointerId = inTouch.identifier + 2;
var ci = dispatcher.captureInfo;
var t = ci && ci.id === pi && ci.target;
e.target = t || findTarget(e);
var id = e.pointerId = inTouch.identifier + 2;
e.target = captureInfo[id] || findTarget(e);
e.bubbles = true;
e.cancelable = true;
e.detail = this.clickCount;
Expand Down
29 changes: 25 additions & 4 deletions test/capture.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
*/

suite('Pointer Capture', function() {
var set = function(el) {
el.setPointerCapture(1);
var set = function(el, id) {
el.setPointerCapture(id || 1);
};
var release = function(el) {
el.releasePointerCapture(1);
var release = function(el, id) {
el.releasePointerCapture(id || 1);
};

test('Element has setPointerCapture and releasePointerCapture', function() {
Expand Down Expand Up @@ -90,5 +90,26 @@ suite('Pointer Capture', function() {
fire('up', host);
}
});

test('capture multiple pointers', function(done) {
var pm = PointerEventsPolyfill.dispatcher.pointermap;
var ids = 0;
function wait(e) {
ids += e.pointerId;
if (ids == 3) {
pm.clear();
done();
}
}
host.addEventListener('gotpointercapture', wait);
var e = new PointerEvent('pointerdown', {pointerId: 1});
pm.set(1, e);
host.dispatchEvent(e);
set(host, 1);
e = new PointerEvent('pointerdown', {pointerId: 2});
pm.set(2, e);
host.dispatchEvent(e);
set(host, 2);
});
});
});

0 comments on commit 1fc32b7

Please sign in to comment.