From 3521bac90e2651ca5df61e8e297611136be7cefc Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Tue, 5 Aug 2014 13:56:18 -0700 Subject: [PATCH] Fixed pointer event capture, Cleaned up debug code --- src/button.js | 2 - src/mousetracker.js | 339 +++++++++++++------------------------- src/navigator.js | 15 +- test/legacy.mouse.shim.js | 10 +- 4 files changed, 116 insertions(+), 250 deletions(-) diff --git a/src/button.js b/src/button.js index b399ccd1..0066efb9 100644 --- a/src/button.js +++ b/src/button.js @@ -212,7 +212,6 @@ $.Button = function( options ) { clickDistThreshold: this.clickDistThreshold, enterHandler: function( event ) { - $.console.log('Enter ');// + event.currentTarget.className); if ( event.insideElementPressed ) { inTo( _this, $.ButtonState.DOWN ); /** @@ -247,7 +246,6 @@ $.Button = function( options ) { }, exitHandler: function( event ) { - $.console.log('Exit ');// + event.currentTarget.className); outTo( _this, $.ButtonState.GROUP ); if ( event.insideElementPressed ) { /** diff --git a/src/mousetracker.js b/src/mousetracker.js index fedd0295..8e096b6e 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -122,28 +122,28 @@ * @member {Number} clickTimeThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.clickTimeThreshold = options.clickTimeThreshold; + this.clickTimeThreshold = options.clickTimeThreshold || $.DEFAULT_SETTINGS.clickTimeThreshold; /** * The maximum distance allowed between a pointer down event and a pointer up event * to be treated as a click gesture. * @member {Number} clickDistThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.clickDistThreshold = options.clickDistThreshold; + this.clickDistThreshold = options.clickDistThreshold || $.DEFAULT_SETTINGS.clickDistThreshold; /** * The number of milliseconds within which two pointer down-up event combinations * will be treated as a double-click gesture. * @member {Number} dblClickTimeThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.dblClickTimeThreshold = options.dblClickTimeThreshold; + this.dblClickTimeThreshold = options.dblClickTimeThreshold || $.DEFAULT_SETTINGS.dblClickTimeThreshold; /** * The maximum distance allowed between two pointer click events * to be treated as a click gesture. * @member {Number} clickDistThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.dblClickDistThreshold = options.dblClickDistThreshold; + this.dblClickDistThreshold = options.dblClickDistThreshold || $.DEFAULT_SETTINGS.dblClickDistThreshold; this.userData = options.userData || null; this.stopDelay = options.stopDelay || 50; @@ -187,8 +187,6 @@ mouseover: function ( event ) { onMouseOver( _this, event ); }, mouseout: function ( event ) { onMouseOut( _this, event ); }, - mouseenter: function ( event ) { onMouseEnter( _this, event ); }, - mouseleave: function ( event ) { onMouseLeave( _this, event ); }, mousedown: function ( event ) { onMouseDown( _this, event ); }, mouseup: function ( event ) { onMouseUp( _this, event ); }, mouseupcaptured: function ( event ) { onMouseUpCaptured( _this, event ); }, @@ -209,10 +207,6 @@ MSPointerOver: function ( event ) { onPointerOver( _this, event ); }, pointerout: function ( event ) { onPointerOut( _this, event ); }, MSPointerOut: function ( event ) { onPointerOut( _this, event ); }, - pointerenter: function ( event ) { onPointerEnter( _this, event ); }, - MSPointerEnter: function ( event ) { onPointerEnter( _this, event ); }, - pointerleave: function ( event ) { onPointerLeave( _this, event ); }, - MSPointerLeave: function ( event ) { onPointerLeave( _this, event ); }, pointerdown: function ( event ) { onPointerDown( _this, event ); }, MSPointerDown: function ( event ) { onPointerDown( _this, event ); }, pointerup: function ( event ) { onPointerUp( _this, event ); }, @@ -232,9 +226,12 @@ // of the element (for hover-capable devices) and/or have contact or a button press initiated in the element. activePointersLists: [], - // Legacy mouse event tracking + // Legacy mouse capture tracking capturing: false, + // Pointer event model capture tracking + pointerCaptureCount: 0, + // Tracking for double-click gesture lastClickPos: null, dblClickTimeOut: null, @@ -821,7 +818,6 @@ } if ( window.PointerEvent ) { - $.console.log('***** Pointer Event Model'); // IE11 and other W3C Pointer Event implementations (see http://www.w3.org/TR/pointerevents) $.MouseTracker.subscribeEvents.push( "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" ); $.MouseTracker.unprefixedPointerEvents = true; @@ -833,7 +829,6 @@ $.MouseTracker.haveTouchEnter = false; $.MouseTracker.haveMouseEnter = false; } else if ( window.MSPointerEvent ) { - $.console.log('***** Pointer Event Model (Prefixed IE10)'); // IE10 $.MouseTracker.subscribeEvents.push( "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" ); $.MouseTracker.unprefixedPointerEvents = false; @@ -845,17 +840,9 @@ $.MouseTracker.haveTouchEnter = false; $.MouseTracker.haveMouseEnter = false; } else { - $.console.log('***** Legacy Event Model'); // Legacy W3C mouse events - // TODO: Favor mouseenter/mouseleave over mouseover/mouseout when Webkit browser support is better - $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); - //if ( $.Browser.vendor == $.BROWSERS.IE ) { - // $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); - // $.MouseTracker.haveMouseEnter = true; - //} else { - $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); - $.MouseTracker.haveMouseEnter = false; - //} + $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); + $.MouseTracker.haveMouseEnter = false; if ( 'ontouchstart' in window ) { // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" ); @@ -1101,25 +1088,20 @@ var delegate = THIS[ tracker.hash ]; if ( !delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.setCapture( true ); -// } else { - // For browsers without setCapture()/releaseCapture(), we emulate mouse capture by hanging listeners on the window object. - // (Note we listen on the capture phase so the captured handlers will get called first) - $.addEvent( - window, - "mouseup", - delegate.mouseupcaptured, - true - ); - $.addEvent( - window, - "mousemove", - delegate.mousemovecaptured, - true - ); -// } + // We emulate mouse capture by hanging listeners on the window object. + // (Note we listen on the capture phase so the captured handlers will get called first) + $.addEvent( + window, + "mouseup", + delegate.mouseupcaptured, + true + ); + $.addEvent( + window, + "mousemove", + delegate.mousemovecaptured, + true + ); delegate.capturing = true; } } @@ -1134,25 +1116,82 @@ var delegate = THIS[ tracker.hash ]; if ( delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.releaseCapture(); -// } else { - // For browsers without setCapture()/releaseCapture(), we emulate mouse capture by hanging listeners on the window object. - // (Note we listen on the capture phase so the captured handlers will get called first) - $.removeEvent( - window, - "mousemove", - delegate.mousemovecaptured, - true - ); - $.removeEvent( - window, - "mouseup", - delegate.mouseupcaptured, - true - ); -// } + // We emulate mouse capture by hanging listeners on the window object. + // (Note we listen on the capture phase so the captured handlers will get called first) + $.removeEvent( + window, + "mousemove", + delegate.mousemovecaptured, + true + ); + $.removeEvent( + window, + "mouseup", + delegate.mouseupcaptured, + true + ); + delegate.capturing = false; + } + } + + + /** + * Begin capturing pointer events to the tracked element (pointer event model only). + * @private + * @inner + */ + function capturePointer( tracker ) { + var delegate = THIS[ tracker.hash ]; + + delegate.pointerCaptureCount++; + //$.console.log('pointerCaptureCount++ ', delegate.pointerCaptureCount); + + if ( delegate.pointerCaptureCount === 1 ) { + // We emulate mouse capture by hanging listeners on the window object. + // (Note we listen on the capture phase so the captured handlers will get called first) + $.addEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', + delegate.pointerupcaptured, + true + ); + $.addEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', + delegate.pointermovecaptured, + true + ); + delegate.capturing = true; + } + } + + + /** + * Stop capturing pointer events to the tracked element (pointer event model only). + * @private + * @inner + */ + function releasePointer( tracker ) { + var delegate = THIS[ tracker.hash ]; + + delegate.pointerCaptureCount--; + //$.console.log('pointerCaptureCount-- ', delegate.pointerCaptureCount); + + if ( delegate.pointerCaptureCount === 0 ) { + // We emulate mouse capture by hanging listeners on the window object. + // (Note we listen on the capture phase so the captured handlers will get called first) + $.removeEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', + delegate.pointermovecaptured, + true + ); + $.removeEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', + delegate.pointerupcaptured, + true + ); delegate.capturing = false; } } @@ -1477,48 +1516,6 @@ } - /** - * @private - * @inner - */ - function onMouseEnter( tracker, event ) { - var gPoint; - - event = $.getEvent( event ); - - gPoint = { - id: $.MouseTracker.mousePointerId, - type: 'mouse', - isPrimary: true, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersEnter( tracker, event, [ gPoint ] ); - } - - - /** - * @private - * @inner - */ - function onMouseLeave( tracker, event ) { - var gPoint; - - event = $.getEvent( event ); - - gPoint = { - id: $.MouseTracker.mousePointerId, - type: 'mouse', - isPrimary: true, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersExit( tracker, event, [ gPoint ] ); - } - - /** * @private * @inner @@ -1557,8 +1554,6 @@ /** * This handler is attached to the window object (on the capture phase) to emulate mouse capture. - * Only triggered in W3C browsers that don't have setCapture/releaseCapture - * methods or don't support the new pointer events model. * onMouseUp is still attached to the tracked element, so stop propagation to avoid processing twice. * * @private @@ -1604,8 +1599,6 @@ /** * This handler is attached to the window object (on the capture phase) to emulate mouse capture. - * Only triggered in W3C browsers that don't have setCapture/releaseCapture - * methods or don't support the new pointer events model. * onMouseMove is still attached to the tracked element, so stop propagation to avoid processing twice. * * @private @@ -1867,110 +1860,6 @@ } - /** - * @private - * @inner - */ - function onPointerEnter( tracker, event ) { - var gPoint; - - gPoint = { - id: event.pointerId, - type: getPointerType( event ), - isPrimary: event.isPrimary, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersEnter( tracker, event, [ gPoint ] ); - } - - - /** - * @private - * @inner - */ - function onPointerLeave( tracker, event ) { - var gPoint; - - gPoint = { - id: event.pointerId, - type: getPointerType( event ), - isPrimary: event.isPrimary, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersExit( tracker, event, [ gPoint ] ); - } - - - /** - * Begin capturing pointer events to the tracked element (pointer event model only). - * @private - * @inner - */ - function capturePointer( tracker ) { - var delegate = THIS[ tracker.hash ]; - - if ( !delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.setCapture( true ); -// } else { - // For browsers without setCapture()/releaseCapture(), we emulate mouse capture by hanging listeners on the window object. - // (Note we listen on the capture phase so the captured handlers will get called first) - $.addEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', - delegate.pointerupcaptured, - true - ); - $.addEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', - delegate.pointermovecaptured, - true - ); -// } - delegate.capturing = true; - } - } - - - /** - * Stop capturing pointer events to the tracked element (pointer event model only). - * @private - * @inner - */ - function releasePointer( tracker ) { - var delegate = THIS[ tracker.hash ]; - - if ( delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.releaseCapture(); -// } else { - // For browsers without setCapture()/releaseCapture(), we emulate mouse capture by hanging listeners on the window object. - // (Note we listen on the capture phase so the captured handlers will get called first) - $.removeEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', - delegate.pointermovecaptured, - true - ); - $.removeEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', - delegate.pointerupcaptured, - true - ); -// } - delegate.capturing = false; - } - } - - /** * @private * @inner @@ -1987,11 +1876,6 @@ }; if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { -// if ( $.MouseTracker.unprefixedPointerEvents ) { -// event.currentTarget.setPointerCapture( event.pointerId ); -// } else { -// event.currentTarget.msSetPointerCapture( event.pointerId ); -// } capturePointer( tracker ); $.stopEvent( event ); } @@ -2019,7 +1903,10 @@ * @inner */ function onPointerUpCaptured( tracker, event ) { - handlePointerUp( tracker, event ); + var pointsList = tracker.getActivePointersListByType( getPointerType( event ) ); + if ( pointsList.getById( event.pointerId ) ) { + handlePointerUp( tracker, event ); + } $.stopEvent( event ); } @@ -2040,13 +1927,8 @@ }; if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { -// if ( $.MouseTracker.unprefixedPointerEvents ) { -// event.currentTarget.releasePointerCapture( event.pointerId ); -// } else { -// event.currentTarget.msReleasePointerCapture( event.pointerId ); -// } releasePointer( tracker ); -// $.stopEvent( event ); + //$.stopEvent( event ); } } @@ -2068,7 +1950,10 @@ * @inner */ function onPointerMoveCaptured( tracker, event ) { - handlePointerMove( tracker, event ); + var pointsList = tracker.getActivePointersListByType( getPointerType( event ) ); + if ( pointsList.getById( event.pointerId ) ) { + handlePointerMove( tracker, event ); + } $.stopEvent( event ); } @@ -2141,7 +2026,6 @@ gPoint.lastPos = gPoint.currentPos; gPoint.lastTime = gPoint.currentTime; -// $.console.log('startTrackingPointer() ', pointsList.getLength() + 1); return pointsList.add( gPoint ); } @@ -2177,7 +2061,6 @@ listLength = pointsList.getLength(); } -// $.console.log('stopTrackingPointer() ', listLength); return listLength; } @@ -2392,7 +2275,7 @@ } pointsList.contacts++; - $.console.log('contacts++ ', pointsList.contacts); + //$.console.log('contacts++ ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { $.MouseTracker.gesturePointVelocityTracker.addPoint( tracker, curGPoint ); @@ -2519,7 +2402,7 @@ // Pointer was activated in our element but could have been removed in any element since events are captured to our element pointsList.contacts--; - $.console.log('contacts-- ', pointsList.contacts); + //$.console.log('contacts-- ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { $.MouseTracker.gesturePointVelocityTracker.removePoint( tracker, updateGPoint ); diff --git a/src/navigator.js b/src/navigator.js index 20082900..a3fda4f5 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -321,17 +321,9 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* * @function */ function onCanvasClick( event ) { - var newBounds, - viewerPosition, - dimensions; - if (! this.drag) { - if ( this.viewer.viewport ) { - this.viewer.viewport.panTo( this.viewport.pointFromPixel( event.position ) ); - this.viewer.viewport.applyConstraints(); - } - } - else { - this.drag = false; + if ( event.quick && this.viewer.viewport ) { + this.viewer.viewport.panTo( this.viewport.pointFromPixel( event.position ) ); + this.viewer.viewport.applyConstraints(); } } @@ -342,7 +334,6 @@ function onCanvasClick( event ) { */ function onCanvasDrag( event ) { if ( this.viewer.viewport ) { - this.drag = true; if( !this.panHorizontal ){ event.delta.x = 0; } diff --git a/test/legacy.mouse.shim.js b/test/legacy.mouse.shim.js index 4d27c39a..7a8ff7cc 100644 --- a/test/legacy.mouse.shim.js +++ b/test/legacy.mouse.shim.js @@ -11,14 +11,8 @@ $.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" ); } - $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); - if ( $.Browser.vendor == $.BROWSERS.IE ) { - $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); - $.MouseTracker.haveMouseEnter = true; - } else { - $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); - $.MouseTracker.haveMouseEnter = false; - } + $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); + $.MouseTracker.haveMouseEnter = false; if ( 'ontouchstart' in window ) { // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" );