diff --git a/changelog.txt b/changelog.txt index 3343c616..48f076a5 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,13 +1,21 @@ OPENSEADRAGON CHANGELOG ======================= -0.9.131: (in progress) +1.0.0: (in progress) + +* MouseTracker now passes the original event objects to its handler methods (#23) +* Breaking change: MouseTracker event handler method signatures changed to 'handlerMethod( tracker, eventData)' (#23) +* MouseTracker now supports an optional 'moveHandler' method for tracking mousemove events (#215) +* Fixed: Element-relative mouse coordinates now correct if the element and/or page is scrolled (using new OpenSeadragon.getElementOffset() method) (#131) + +0.9.131: * Fixed: canvas-click event shouldn't fire as you drag (#198) * Fixed: LegacyTileSource doesn't fail gracefully when no supported file formats are found (#202) * Added an optional userData argument to EventHandler.addHandler() which is passed unchanged to the handler method (#203) * Fixed AJAX error reporting on IE8 (#208) * Added viewportToImageRectangle method, and updated imageToViewportRectangle, imageToViewportCoordinates, and viewportToImageCoordinates to be more flexible with params (#212) +* Fixed: Viewer is not responsive (css) after returning from full screen (#222) 0.9.130: diff --git a/package.json b/package.json index 6eb21c7a..73c90e02 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "OpenSeadragon", - "version": "0.9.130", + "version": "0.9.131", "description": "Provides a smooth, zoomable user interface for HTML/Javascript.", "devDependencies": { "grunt": "~0.4.0", diff --git a/src/button.js b/src/button.js index 7eead5da..f6aca329 100644 --- a/src/button.js +++ b/src/button.js @@ -175,57 +175,57 @@ $.Button = function( options ) { clickTimeThreshold: this.clickTimeThreshold, clickDistThreshold: this.clickDistThreshold, - enterHandler: function( tracker, position, buttonDownElement, buttonDownAny ) { - if ( buttonDownElement ) { + enterHandler: function( tracker, eventData ) { + if ( eventData.insideElementPressed ) { inTo( _this, $.ButtonState.DOWN ); _this.raiseEvent( "onEnter", _this ); - } else if ( !buttonDownAny ) { + } else if ( !eventData.buttonDownAny ) { inTo( _this, $.ButtonState.HOVER ); } }, - focusHandler: function( tracker, position, buttonDownElement, buttonDownAny ) { - this.enterHandler( tracker, position, buttonDownElement, buttonDownAny ); + focusHandler: function ( tracker, eventData ) { + this.enterHandler( tracker, eventData ); _this.raiseEvent( "onFocus", _this ); }, - exitHandler: function( tracker, position, buttonDownElement, buttonDownAny ) { + exitHandler: function( tracker, eventData ) { outTo( _this, $.ButtonState.GROUP ); - if ( buttonDownElement ) { + if ( eventData.insideElementPressed ) { _this.raiseEvent( "onExit", _this ); } }, - blurHandler: function( tracker, position, buttonDownElement, buttonDownAny ) { - this.exitHandler( tracker, position, buttonDownElement, buttonDownAny ); + blurHandler: function ( tracker, eventData ) { + this.exitHandler( tracker, eventData ); _this.raiseEvent( "onBlur", _this ); }, - pressHandler: function( tracker, position ) { + pressHandler: function ( tracker, eventData ) { inTo( _this, $.ButtonState.DOWN ); _this.raiseEvent( "onPress", _this ); }, - releaseHandler: function( tracker, position, insideElementPress, insideElementRelease ) { - if ( insideElementPress && insideElementRelease ) { + releaseHandler: function( tracker, eventData ) { + if ( eventData.insideElementPressed && eventData.insideElementReleased ) { outTo( _this, $.ButtonState.HOVER ); _this.raiseEvent( "onRelease", _this ); - } else if ( insideElementPress ) { + } else if ( eventData.insideElementPressed ) { outTo( _this, $.ButtonState.GROUP ); } else { inTo( _this, $.ButtonState.HOVER ); } }, - clickHandler: function( tracker, position, quick, shift ) { - if ( quick ) { + clickHandler: function( tracker, eventData ) { + if ( eventData.quick ) { _this.raiseEvent("onClick", _this); } }, - keyHandler: function( tracker, key ){ - //console.log( "%s : handling key %s!", _this.tooltip, key); - if( 13 === key ){ + keyHandler: function( tracker, eventData ){ + //console.log( "%s : handling key %s!", _this.tooltip, eventData.keyCode); + if( 13 === eventData.keyCode ){ _this.raiseEvent( "onClick", _this ); _this.raiseEvent( "onRelease", _this ); return false; diff --git a/src/buttongroup.js b/src/buttongroup.js index 17c08267..5adaf09e 100644 --- a/src/buttongroup.js +++ b/src/buttongroup.js @@ -85,29 +85,23 @@ $.ButtonGroup = function( options ) { element: this.element, clickTimeThreshold: this.clickTimeThreshold, clickDistThreshold: this.clickDistThreshold, - enterHandler: function() { + enterHandler: function ( tracker, eventData ) { var i; for ( i = 0; i < _this.buttons.length; i++ ) { _this.buttons[ i ].notifyGroupEnter(); } }, - exitHandler: function() { - var i, - buttonDownElement = arguments.length > 2 ? - arguments[ 2 ] : - null; - if ( !buttonDownElement ) { + exitHandler: function ( tracker, eventData ) { + var i; + if ( !eventData.insideElementPressed ) { for ( i = 0; i < _this.buttons.length; i++ ) { _this.buttons[ i ].notifyGroupExit(); } } }, - releaseHandler: function() { - var i, - insideElementRelease = arguments.length > 3 ? - arguments[ 3 ] : - null; - if ( !insideElementRelease ) { + releaseHandler: function ( tracker, eventData ) { + var i; + if ( !eventData.insideElementReleased ) { for ( i = 0; i < _this.buttons.length; i++ ) { _this.buttons[ i ].notifyGroupExit(); } @@ -125,7 +119,7 @@ $.ButtonGroup.prototype = { * @name OpenSeadragon.ButtonGroup.prototype.emulateEnter */ emulateEnter: function() { - this.tracker.enterHandler(); + this.tracker.enterHandler( this.tracker, {} ); }, /** @@ -135,7 +129,7 @@ $.ButtonGroup.prototype = { * @name OpenSeadragon.ButtonGroup.prototype.emulateExit */ emulateExit: function() { - this.tracker.exitHandler(); + this.tracker.exitHandler( this.tracker, {} ); } }; diff --git a/src/eventhandler.js b/src/eventhandler.js index 56fbf080..51fa54a1 100644 --- a/src/eventhandler.js +++ b/src/eventhandler.js @@ -55,7 +55,7 @@ $.EventHandler.prototype = { * @function * @param {String} eventName - Name of event to register. * @param {Function} handler - Function to call when event is triggered. - * @param {Object} optional userData - Arbitrary object to be passed to the handler. + * @param {Object} [userData=null] - Arbitrary object to be passed unchanged to the handler. */ addHandler: function ( eventName, handler, userData ) { var events = this.events[ eventName ]; diff --git a/src/mousetracker.js b/src/mousetracker.js index f2dd53f8..5161c879 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -32,18 +32,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -(function( $ ){ +(function ( $ ) { // is any button currently being pressed while mouse events occur - var IS_BUTTON_DOWN = false, + var IS_BUTTON_DOWN = false, // is any tracker currently capturing? - IS_CAPTURING = false, + IS_CAPTURING = false, // dictionary from hash to MouseTracker - ACTIVE = {}, + ACTIVE = {}, // list of trackers interested in capture - CAPTURING = [], + CAPTURING = [], // dictionary from hash to private properties - THIS = {}; + THIS = {}; /** * The MouseTracker allows other classes to set handlers for common mouse @@ -72,12 +72,22 @@ * An optional handler for mouse press. * @param {Function} options.releaseHandler * An optional handler for mouse release. + * @param {Function} options.moveHandler + * An optional handler for mouse move. * @param {Function} options.scrollHandler * An optional handler for mouse scroll. * @param {Function} options.clickHandler * An optional handler for mouse click. * @param {Function} options.dragHandler * An optional handler for mouse drag. + * @param {Function} options.keyHandler + * An optional handler for keypress. + * @param {Function} options.focusHandler + * An optional handler for focus. + * @param {Function} options.blurHandler + * An optional handler for blur. + * @param {Object} [options.userData=null] + * Arbitrary object to be passed unchanged to any attached handler methods. * @property {Number} hash * An unique hash for this tracker. * @property {Element} element @@ -91,9 +101,9 @@ */ $.MouseTracker = function ( options ) { - var args = arguments; + var args = arguments; - if( !$.isPlainObject( options ) ){ + if ( !$.isPlainObject( options ) ) { options = { element: args[ 0 ], clickTimeThreshold: args[ 1 ], @@ -105,12 +115,13 @@ this.element = $.getElement( options.element ); this.clickTimeThreshold = options.clickTimeThreshold; this.clickDistThreshold = options.clickDistThreshold; - + this.userData = options.userData || null; this.enterHandler = options.enterHandler || null; this.exitHandler = options.exitHandler || null; this.pressHandler = options.pressHandler || null; this.releaseHandler = options.releaseHandler || null; + this.moveHandler = options.moveHandler || null; this.scrollHandler = options.scrollHandler || null; this.clickHandler = options.clickHandler || null; this.dragHandler = options.dragHandler || null; @@ -127,7 +138,7 @@ * Are we currently tracking mouse events. * @property {Boolean} capturing * Are we curruently capturing mouse events. - * @property {Boolean} buttonDown + * @property {Boolean} insideElementPressed * True if the left mouse button is currently being pressed and was * initiated inside the tracked element, otherwise false. * @property {Boolean} insideElement @@ -140,31 +151,32 @@ * Position of last mouse down */ THIS[ this.hash ] = { - mouseover: function( event ){ onMouseOver( _this, event ); }, - mouseout: function( event ){ onMouseOut( _this, event ); }, - mousedown: function( event ){ onMouseDown( _this, event ); }, - mouseup: function( event ){ onMouseUp( _this, event ); }, - click: function( event ){ onMouseClick( _this, event ); }, - DOMMouseScroll: function( event ){ onMouseWheelSpin( _this, event ); }, - mousewheel: function( event ){ onMouseWheelSpin( _this, event ); }, - mouseupie: function( event ){ onMouseUpIE( _this, event ); }, - mousemoveie: function( event ){ onMouseMoveIE( _this, event ); }, - mouseupwindow: function( event ){ onMouseUpWindow( _this, event ); }, - mousemove: function( event ){ onMouseMove( _this, event ); }, - touchstart: function( event ){ onTouchStart( _this, event ); }, - touchmove: function( event ){ onTouchMove( _this, event ); }, - touchend: function( event ){ onTouchEnd( _this, event ); }, - keypress: function( event ){ onKeyPress( _this, event ); }, - focus: function( event ){ onFocus( _this, event ); }, - blur: function( event ){ onBlur( _this, event ); }, - tracking: false, - capturing: false, - buttonDown: false, - insideElement: false, - lastPoint: null, - lastMouseDownTime: null, - lastMouseDownPoint: null, - lastPinchDelta: 0 + mouseover: function ( event ) { onMouseOver( _this, event, false ); }, + mouseout: function ( event ) { onMouseOut( _this, event, false ); }, + mousedown: function ( event ) { onMouseDown( _this, event ); }, + mouseup: function ( event ) { onMouseUp( _this, event, false ); }, + mousemove: function ( event ) { onMouseMove( _this, event ); }, + click: function ( event ) { onMouseClick( _this, event ); }, + DOMMouseScroll: function ( event ) { onMouseWheelSpin( _this, event, false ); }, + mousewheel: function ( event ) { onMouseWheelSpin( _this, event, false ); }, + mouseupie: function ( event ) { onMouseUpIE( _this, event ); }, + mousemovecapturedie: function ( event ) { onMouseMoveCapturedIE( _this, event ); }, + mouseupcaptured: function ( event ) { onMouseUpCaptured( _this, event ); }, + mousemovecaptured: function ( event ) { onMouseMoveCaptured( _this, event, false ); }, + touchstart: function ( event ) { onTouchStart( _this, event ); }, + touchmove: function ( event ) { onTouchMove( _this, event ); }, + touchend: function ( event ) { onTouchEnd( _this, event ); }, + keypress: function ( event ) { onKeyPress( _this, event ); }, + focus: function ( event ) { onFocus( _this, event ); }, + blur: function ( event ) { onBlur( _this, event ); }, + tracking: false, + capturing: false, + insideElementPressed: false, + insideElement: false, + lastPoint: null, + lastMouseDownTime: null, + lastMouseDownPoint: null, + lastPinchDelta: 0 }; }; @@ -175,7 +187,7 @@ * Clean up any events or objects created by the mouse tracker. * @function */ - destroy: function() { + destroy: function () { stopTracking( this ); this.element = null; }, @@ -212,15 +224,22 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {OpenSeadragon.Point} position - * The poistion of the event on the screen. - * @param {Boolean} buttonDown + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {Boolean} eventData.insideElementPressed * True if the left mouse button is currently being pressed and was * initiated inside the tracked element, otherwise false. - * @param {Boolean} buttonDownAny + * @param {Boolean} eventData.buttonDownAny * Was the button down anywhere in the screen during the event. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - enterHandler: function(){}, + enterHandler: function () { }, /** * Implement or assign implmentation to these handlers during or after @@ -228,15 +247,22 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {OpenSeadragon.Point} position - * The poistion of the event on the screen. - * @param {Boolean} buttonDown + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {Boolean} eventData.insideElementPressed * True if the left mouse button is currently being pressed and was * initiated inside the tracked element, otherwise false. - * @param {Boolean} buttonDownAny + * @param {Boolean} eventData.buttonDownAny * Was the button down anywhere in the screen during the event. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - exitHandler: function(){}, + exitHandler: function () { }, /** * Implement or assign implmentation to these handlers during or after @@ -244,10 +270,17 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {OpenSeadragon.Point} position - * The poistion of the event on the screen. + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - pressHandler: function(){}, + pressHandler: function () { }, /** * Implement or assign implmentation to these handlers during or after @@ -255,16 +288,22 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {OpenSeadragon.Point} position - * The poistion of the event on the screen. - * @param {Boolean} buttonDown + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {Boolean} eventData.insideElementPressed * True if the left mouse button is currently being pressed and was * initiated inside the tracked element, otherwise false. - * @param {Boolean} insideElementRelease - * Was the mouse still inside the tracked element when the button - * was released. + * @param {Boolean} eventData.insideElementReleased + * True if the cursor still inside the tracked element when the button was released. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - releaseHandler: function(){}, + releaseHandler: function () { }, /** * Implement or assign implmentation to these handlers during or after @@ -272,14 +311,39 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {OpenSeadragon.Point} position - * The poistion of the event on the screen. - * @param {Number} scroll + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. + */ + moveHandler: function () { }, + + /** + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {Number} eventData.scroll * The scroll delta for the event. - * @param {Boolean} shift - * Was the shift key being pressed during this event? + * @param {Boolean} eventData.shift + * True if the shift key was pressed during this event. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - scrollHandler: function(){}, + scrollHandler: function () { }, /** * Implement or assign implmentation to these handlers during or after @@ -287,15 +351,21 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {OpenSeadragon.Point} position - * The poistion of the event on the screen. - * @param {Boolean} quick - * True only if the clickDistThreshold and clickDeltaThreshold are - * both pased. Useful for ignoring events. - * @param {Boolean} shift - * Was the shift key being pressed during this event? + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {Number} eventData.quick + * True only if the clickDistThreshold and clickDeltaThreshold are both pased. Useful for ignoring events. + * @param {Boolean} eventData.shift + * True if the shift key was pressed during this event. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - clickHandler: function(){}, + clickHandler: function () { }, /** * Implement or assign implmentation to these handlers during or after @@ -303,15 +373,21 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {OpenSeadragon.Point} position - * The poistion of the event on the screen. - * @param {OpenSeadragon.Point} delta - * The x,y components of the difference between start drag and - * end drag. Usefule for ignoring or weighting the events. - * @param {Boolean} shift - * Was the shift key being pressed during this event? + * @param {Object} eventData + * @param {OpenSeadragon.Point} eventData.position + * The position of the event relative to the tracked element. + * @param {OpenSeadragon.Point} eventData.delta + * The x,y components of the difference between start drag and end drag. Usefule for ignoring or weighting the events. + * @param {Boolean} eventData.shift + * True if the shift key was pressed during this event. + * @param {Boolean} eventData.isTouchEvent + * True if the original event is a touch event, otherwise false. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - dragHandler: function(){}, + dragHandler: function () { }, /** * Implement or assign implmentation to these handlers during or after @@ -319,16 +395,45 @@ * @function * @param {OpenSeadragon.MouseTracker} tracker * A reference to the tracker instance. - * @param {Number} keyCode + * @param {Object} eventData + * @param {Number} eventData.keyCode * The key code that was pressed. - * @param {Boolean} shift - * Was the shift key being pressed during this event? + * @param {Boolean} eventData.shift + * True if the shift key was pressed during this event. + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. */ - keyHandler: function(){}, + keyHandler: function () { }, - focusHandler: function(){}, + /** + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. + */ + focusHandler: function () { }, - blurHandler: function(){} + /** + * Implement or assign implmentation to these handlers during or after + * calling the constructor. + * @function + * @param {OpenSeadragon.MouseTracker} tracker + * A reference to the tracker instance. + * @param {Object} eventData + * @param {Object} eventData.originalEvent + * The original event object. + * @param {Object} eventData.userData + * Arbitrary user-defined object. + */ + blurHandler: function () { } }; /** @@ -338,7 +443,7 @@ */ function startTracking( tracker ) { var events = [ - "mouseover", "mouseout", "mousedown", "mouseup", + "mouseover", "mouseout", "mousedown", "mouseup", "mousemove", "click", "DOMMouseScroll", "mousewheel", "touchstart", "touchmove", "touchend", @@ -350,7 +455,7 @@ i; if ( !delegate.tracking ) { - for( i = 0; i < events.length; i++ ){ + for ( i = 0; i < events.length; i++ ) { event = events[ i ]; $.addEvent( tracker.element, @@ -371,7 +476,7 @@ */ function stopTracking( tracker ) { var events = [ - "mouseover", "mouseout", "mousedown", "mouseup", + "mouseover", "mouseout", "mousedown", "mouseup", "mousemove", "click", "DOMMouseScroll", "mousewheel", "touchstart", "touchmove", "touchend", @@ -383,7 +488,7 @@ i; if ( delegate.tracking ) { - for( i = 0; i < events.length; i++ ){ + for ( i = 0; i < events.length; i++ ) { event = events[ i ]; $.removeEvent( tracker.element, @@ -432,20 +537,20 @@ $.addEvent( tracker.element, "mousemove", - delegate.mousemoveie, + delegate.mousemovecapturedie, true ); } else { $.addEvent( window, "mouseup", - delegate.mouseupwindow, + delegate.mouseupcaptured, true ); $.addEvent( window, "mousemove", - delegate.mousemove, + delegate.mousemovecaptured, true ); } @@ -467,7 +572,7 @@ $.removeEvent( tracker.element, "mousemove", - delegate.mousemoveie, + delegate.mousemovecapturedie, true ); $.removeEvent( @@ -486,13 +591,13 @@ $.removeEvent( window, "mousemove", - delegate.mousemove, + delegate.mousemovecaptured, true ); $.removeEvent( window, "mouseup", - delegate.mouseupwindow, + delegate.mouseupcaptured, true ); } @@ -505,11 +610,11 @@ * @private * @inner */ - function triggerOthers( tracker, handler, event ) { + function triggerOthers( tracker, handler, event, isTouch ) { var otherHash; for ( otherHash in ACTIVE ) { if ( ACTIVE.hasOwnProperty( otherHash ) && tracker.hash != otherHash ) { - handler( ACTIVE[ otherHash ], event ); + handler( ACTIVE[ otherHash ], event, isTouch ); } } } @@ -519,15 +624,18 @@ * @private * @inner */ - function onFocus( tracker, event ){ + function onFocus( tracker, event ) { //console.log( "focus %s", event ); var propagate; if ( tracker.focusHandler ) { propagate = tracker.focusHandler( tracker, - event + { + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -538,15 +646,18 @@ * @private * @inner */ - function onBlur( tracker, event ){ + function onBlur( tracker, event ) { //console.log( "blur %s", event ); var propagate; if ( tracker.blurHandler ) { propagate = tracker.blurHandler( tracker, - event + { + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -557,16 +668,21 @@ * @private * @inner */ - function onKeyPress( tracker, event ){ + function onKeyPress( tracker, event ) { //console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); var propagate; if ( tracker.keyHandler ) { propagate = tracker.keyHandler( tracker, - event.keyCode ? event.keyCode : event.charCode, - event.shiftKey + { + position: getMouseRelative( event, tracker.element ), + keyCode: event.keyCode ? event.keyCode : event.charCode, + shift: event.shiftKey, + originalEvent: event, + userData: tracker.userData + } ); - if( !propagate ){ + if ( !propagate ) { $.cancelEvent( event ); } } @@ -577,31 +693,35 @@ * @private * @inner */ - function onMouseOver( tracker, event ) { + function onMouseOver( tracker, event, isTouch ) { var delegate = THIS[ tracker.hash ], propagate; + isTouch = isTouch || false; + event = $.getEvent( event ); - if ( $.Browser.vendor == $.BROWSERS.IE && - $.Browser.version < 9 && - delegate.capturing && - !isChild( event.srcElement, tracker.element ) ) { + if ( !isTouch ) { + if ( $.Browser.vendor == $.BROWSERS.IE && + $.Browser.version < 9 && + delegate.capturing && + !isChild( event.srcElement, tracker.element ) ) { - triggerOthers( tracker, onMouseOver, event ); - } + triggerOthers( tracker, onMouseOver, event, isTouch ); + } - var to = event.target ? - event.target : - event.srcElement, - from = event.relatedTarget ? - event.relatedTarget : - event.fromElement; + var to = event.target ? + event.target : + event.srcElement, + from = event.relatedTarget ? + event.relatedTarget : + event.fromElement; - if ( !isChild( tracker.element, to ) || - isChild( tracker.element, from ) ) { - return; + if ( !isChild( tracker.element, to ) || + isChild( tracker.element, from ) ) { + return; + } } delegate.insideElement = true; @@ -609,11 +729,16 @@ if ( tracker.enterHandler ) { propagate = tracker.enterHandler( tracker, - getMouseRelative( event, tracker.element ), - delegate.buttonDown, - IS_BUTTON_DOWN + { + position: getMouseRelative( isTouch ? event.changedTouches[ 0 ] : event, tracker.element ), + insideElementPressed: delegate.insideElementPressed, + buttonDownAny: IS_BUTTON_DOWN, + isTouchEvent: isTouch, + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -624,31 +749,35 @@ * @private * @inner */ - function onMouseOut( tracker, event ) { + function onMouseOut( tracker, event, isTouch ) { var delegate = THIS[ tracker.hash ], propagate; + isTouch = isTouch || false; + event = $.getEvent( event ); - if ( $.Browser.vendor == $.BROWSERS.IE && - $.Browser.version < 9 && - delegate.capturing && - !isChild( event.srcElement, tracker.element ) ) { + if ( !isTouch ) { + if ( $.Browser.vendor == $.BROWSERS.IE && + $.Browser.version < 9 && + delegate.capturing && + !isChild( event.srcElement, tracker.element ) ) { - triggerOthers( tracker, onMouseOut, event ); + triggerOthers( tracker, onMouseOut, event, isTouch ); - } + } - var from = event.target ? - event.target : - event.srcElement, - to = event.relatedTarget ? - event.relatedTarget : - event.toElement; + var from = event.target ? + event.target : + event.srcElement, + to = event.relatedTarget ? + event.relatedTarget : + event.toElement; - if ( !isChild( tracker.element, from ) || - isChild( tracker.element, to ) ) { - return; + if ( !isChild( tracker.element, from ) || + isChild( tracker.element, to ) ) { + return; + } } delegate.insideElement = false; @@ -656,12 +785,17 @@ if ( tracker.exitHandler ) { propagate = tracker.exitHandler( tracker, - getMouseRelative( event, tracker.element ), - delegate.buttonDown, - IS_BUTTON_DOWN + { + position: getMouseRelative( isTouch ? event.changedTouches[ 0 ] : event, tracker.element ), + insideElementPressed: delegate.insideElementPressed, + buttonDownAny: IS_BUTTON_DOWN, + isTouchEvent: isTouch, + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -672,28 +806,37 @@ * @private * @inner */ - function onMouseDown( tracker, event, noCapture ) { + function onMouseDown( tracker, event, noCapture, isTouch ) { var delegate = THIS[ tracker.hash ], propagate; - event = $.getEvent( event ); + isTouch = isTouch || false; + + event = $.getEvent(event); + + var eventOrTouchPoint = isTouch ? event.touches[ 0 ] : event; if ( event.button == 2 ) { return; } - delegate.buttonDown = true; + delegate.insideElementPressed = true; - delegate.lastPoint = getMouseAbsolute( event ); + delegate.lastPoint = getMouseAbsolute( eventOrTouchPoint ); delegate.lastMouseDownPoint = delegate.lastPoint; delegate.lastMouseDownTime = $.now(); if ( tracker.pressHandler ) { propagate = tracker.pressHandler( tracker, - getMouseRelative( event, tracker.element ) + { + position: getMouseRelative( eventOrTouchPoint, tracker.element ), + isTouchEvent: isTouch, + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -705,14 +848,15 @@ if ( noCapture ) { return; } - - if ( !( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) || + + if ( isTouch || + !( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) || !IS_CAPTURING ) { captureMouse( tracker ); IS_CAPTURING = true; // reset to empty & add us CAPTURING = [ tracker ]; - } else if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) { + } else if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) { // add us to the list CAPTURING.push( tracker ); } @@ -726,18 +870,18 @@ var touchA, touchB; - if( event.touches.length == 1 && + if ( event.touches.length == 1 && event.targetTouches.length == 1 && - event.changedTouches.length == 1 ){ + event.changedTouches.length == 1 ) { THIS[ tracker.hash ].lastTouch = event.touches[ 0 ]; - onMouseOver( tracker, event.changedTouches[ 0 ] ); - // call with no capture as the onMouseMove will + onMouseOver( tracker, event, true ); + // call with no capture as the onMouseMoveCaptured will // be triggered by onTouchMove - onMouseDown( tracker, event.touches[ 0 ], true ); + onMouseDown( tracker, event, true, true ); } - if( event.touches.length == 2 ){ + if ( event.touches.length == 2 ) { touchA = getMouseAbsolute( event.touches[ 0 ] ); touchB = getMouseAbsolute( event.touches[ 1 ] ); @@ -745,7 +889,7 @@ Math.abs( touchA.x - touchB.x ) + Math.abs( touchA.y - touchB.y ); THIS[ tracker.hash ].pinchMidpoint = new $.Point( - ( touchA.x + touchB.x ) / 2 , + ( touchA.x + touchB.x ) / 2, ( touchA.y + touchB.y ) / 2 ); //$.console.debug("pinch start : "+THIS[ tracker.hash ].lastPinchDelta); @@ -759,36 +903,43 @@ * @private * @inner */ - function onMouseUp( tracker, event ) { + function onMouseUp( tracker, event, isTouch ) { var delegate = THIS[ tracker.hash ], //were we inside the tracked element when we were pressed - insideElementPress = delegate.buttonDown, + insideElementPressed = delegate.insideElementPressed, //are we still inside the tracked element when we released - insideElementRelease = delegate.insideElement, + insideElementReleased = delegate.insideElement, propagate; - event = $.getEvent( event ); + isTouch = isTouch || false; + + event = $.getEvent(event); if ( event.button == 2 ) { return; } - delegate.buttonDown = false; + delegate.insideElementPressed = false; if ( tracker.releaseHandler ) { propagate = tracker.releaseHandler( tracker, - getMouseRelative( event, tracker.element ), - insideElementPress, - insideElementRelease + { + position: getMouseRelative( isTouch ? event.changedTouches[ 0 ] : event, tracker.element ), + insideElementPressed: insideElementPressed, + insideElementReleased: insideElementReleased, + isTouchEvent: isTouch, + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } - if ( insideElementPress && insideElementRelease ) { - handleMouseClick( tracker, event ); + if ( insideElementPressed && insideElementReleased ) { + handleMouseClick( tracker, event, isTouch ); } } @@ -799,20 +950,20 @@ */ function onTouchEnd( tracker, event ) { - if( event.touches.length === 0 && + if ( event.touches.length === 0 && event.targetTouches.length === 0 && - event.changedTouches.length == 1 ){ + event.changedTouches.length == 1 ) { THIS[ tracker.hash ].lastTouch = null; - + // call with no release, as the mouse events are // not registered in onTouchStart - onMouseUpWindow( tracker, event.changedTouches[ 0 ], true ); - onMouseOut( tracker, event.changedTouches[ 0 ] ); + onMouseUpCaptured( tracker, event, true, true ); + onMouseOut( tracker, event, true ); } - if( event.touches.length + event.changedTouches.length == 2 ){ + if ( event.touches.length + event.changedTouches.length == 2 ) { THIS[ tracker.hash ].lastPinchDelta = null; - THIS[ tracker.hash ].pinchMidpoint = null; + THIS[ tracker.hash ].pinchMidpoint = null; //$.console.debug("pinch end"); } event.preventDefault(); @@ -842,7 +993,7 @@ for ( i = 0; i < CAPTURING.length; i++ ) { othertracker = CAPTURING[ i ]; if ( !hasMouse( othertracker ) ) { - onMouseUp( othertracker, event ); + onMouseUp( othertracker, event, false ); } } @@ -866,12 +1017,14 @@ * @private * @inner */ - function onMouseUpWindow( tracker, event, noRelease ) { - if ( ! THIS[ tracker.hash ].insideElement ) { - onMouseUp( tracker, event ); + function onMouseUpCaptured( tracker, event, noRelease, isTouch ) { + isTouch = isTouch || false; + + if ( !THIS[ tracker.hash ].insideElement ) { + onMouseUp( tracker, event, isTouch ); } - if (noRelease) { + if ( noRelease ) { return; } @@ -879,6 +1032,30 @@ } + /** + * @private + * @inner + */ + function onMouseMove( tracker, event ) { + if ( tracker.moveHandler ) { + event = $.getEvent( event ); + + var propagate = tracker.moveHandler( + tracker, + { + position: getMouseRelative( event, tracker.element ), + isTouchEvent: false, + originalEvent: event, + userData: tracker.userData + } + ); + if ( propagate === false ) { + $.cancelEvent( event ); + } + } + } + + /** * @private * @inner @@ -894,10 +1071,12 @@ * @private * @inner */ - function onMouseWheelSpin( tracker, event ) { + function onMouseWheelSpin( tracker, event, isTouch ) { var nDelta = 0, propagate; + isTouch = isTouch || false; + if ( !event ) { // For IE, access the global (window) event object event = window.event; } @@ -907,7 +1086,7 @@ if ( window.opera ) { // Opera has the values reversed nDelta = -nDelta; } - } else if (event.detail) { // Mozilla FireFox + } else if ( event.detail ) { // Mozilla FireFox nDelta = -event.detail; } //The nDelta variable is gated to provide smooth z-index scrolling @@ -918,11 +1097,19 @@ if ( tracker.scrollHandler ) { propagate = tracker.scrollHandler( tracker, - getMouseRelative( event, tracker.element ), - nDelta, - event.shiftKey + { + // Note: Ok to call getMouseRelative on passed event for isTouch==true since + // event.pageX/event.pageY are added to the original touchmove event in + // onTouchMove(). + position: getMouseRelative( event, tracker.element ), + scroll: nDelta, + shift: event.shiftKey, + isTouchEvent: isTouch, + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -933,30 +1120,39 @@ * @private * @inner */ - function handleMouseClick( tracker, event ) { + function handleMouseClick( tracker, event, isTouch ) { var delegate = THIS[ tracker.hash ], propagate; + isTouch = isTouch || false; + event = $.getEvent( event ); + var eventOrTouchPoint = isTouch ? event.changedTouches[ 0 ] : event; + if ( event.button == 2 ) { return; } - var time = $.now() - delegate.lastMouseDownTime, - point = getMouseAbsolute( event ), + var time = $.now() - delegate.lastMouseDownTime, + point = getMouseAbsolute( eventOrTouchPoint ), distance = delegate.lastMouseDownPoint.distanceTo( point ), - quick = time <= tracker.clickTimeThreshold && + quick = time <= tracker.clickTimeThreshold && distance <= tracker.clickDistThreshold; if ( tracker.clickHandler ) { propagate = tracker.clickHandler( tracker, - getMouseRelative( event, tracker.element ), - quick, - event.shiftKey + { + position: getMouseRelative( eventOrTouchPoint, tracker.element ), + quick: quick, + shift: event.shiftKey, + isTouchEvent: isTouch, + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -967,14 +1163,17 @@ * @private * @inner */ - function onMouseMove( tracker, event ) { + function onMouseMoveCaptured( tracker, event, isTouch ) { var delegate = THIS[ tracker.hash ], delta, propagate, point; - event = $.getEvent( event ); - point = getMouseAbsolute( event ); + isTouch = isTouch || false; + + event = $.getEvent(event); + var eventOrTouchPoint = isTouch ? event.touches[ 0 ] : event; + point = getMouseAbsolute( eventOrTouchPoint ); delta = point.minus( delegate.lastPoint ); delegate.lastPoint = point; @@ -982,11 +1181,16 @@ if ( tracker.dragHandler ) { propagate = tracker.dragHandler( tracker, - getMouseRelative( event, tracker.element ), - delta, - event.shiftKey + { + position: getMouseRelative( eventOrTouchPoint, tracker.element ), + delta: delta, + shift: event.shiftKey, + isTouchEvent: isTouch, + originalEvent: event, + userData: tracker.userData + } ); - if( propagate === false ){ + if ( propagate === false ) { $.cancelEvent( event ); } } @@ -1003,17 +1207,17 @@ pinchDelta; if ( !THIS[ tracker.hash ].lastTouch ) { - return; + return; } - if( event.touches.length === 1 && + if ( event.touches.length === 1 && event.targetTouches.length === 1 && event.changedTouches.length === 1 && - THIS[ tracker.hash ].lastTouch.identifier === event.touches[ 0 ].identifier){ + THIS[ tracker.hash ].lastTouch.identifier === event.touches[ 0 ].identifier ) { - onMouseMove( tracker, event.touches[ 0 ] ); + onMouseMoveCaptured( tracker, event, true ); - } else if ( event.touches.length === 2 ){ + } else if ( event.touches.length === 2 ) { touchA = getMouseAbsolute( event.touches[ 0 ] ); touchB = getMouseAbsolute( event.touches[ 1 ] ); @@ -1022,17 +1226,16 @@ Math.abs( touchA.y - touchB.y ); //TODO: make the 75px pinch threshold configurable - if( Math.abs( THIS[ tracker.hash ].lastPinchDelta - pinchDelta ) > 75 ){ + if ( Math.abs( THIS[ tracker.hash ].lastPinchDelta - pinchDelta ) > 75 ) { //$.console.debug( "pinch delta : " + pinchDelta + " | previous : " + THIS[ tracker.hash ].lastPinchDelta); - onMouseWheelSpin( tracker, { - shift: false, - pageX: THIS[ tracker.hash ].pinchMidpoint.x, - pageY: THIS[ tracker.hash ].pinchMidpoint.y, - detail:( - THIS[ tracker.hash ].lastPinchDelta > pinchDelta - ) ? 1 : -1 - }); + // Adjust the original event enough to simulate a mouse wheel scroll + event.shiftKey = event.shiftKey || false; + event.pageX = THIS[ tracker.hash ].pinchMidpoint.x; + event.pageY = THIS[ tracker.hash ].pinchMidpoint.y; + event.detail = ( THIS[ tracker.hash ].lastPinchDelta > pinchDelta ) ? 1 : -1; + + onMouseWheelSpin( tracker, event, true ); THIS[ tracker.hash ].lastPinchDelta = pinchDelta; } @@ -1049,10 +1252,10 @@ * @private * @inner */ - function onMouseMoveIE( tracker, event ) { + function onMouseMoveCapturedIE( tracker, event ) { var i; for ( i = 0; i < CAPTURING.length; i++ ) { - onMouseMove( CAPTURING[ i ], event ); + onMouseMoveCaptured( CAPTURING[ i ], event, false ); } $.stopEvent( event ); @@ -1067,27 +1270,27 @@ } /** - * @private - * @inner - */ + * @private + * @inner + */ function getMouseRelative( event, element ) { - var mouse = $.getMousePosition( event ), - offset = $.getElementPosition( element ); + var mouse = $.getMousePosition( event ), + offset = $.getElementOffset( element ); return mouse.minus( offset ); } /** - * @private - * @inner - * Returns true if elementB is a child node of elementA, or if they're equal. - */ + * @private + * @inner + * Returns true if elementB is a child node of elementA, or if they're equal. + */ function isChild( elementA, elementB ) { var body = document.body; while ( elementB && elementA != elementB && body != elementB ) { try { elementB = elementB.parentNode; - } catch (e) { + } catch ( e ) { return false; } } @@ -1095,17 +1298,17 @@ } /** - * @private - * @inner - */ + * @private + * @inner + */ function onGlobalMouseDown() { IS_BUTTON_DOWN = true; } /** - * @private - * @inner - */ + * @private + * @inner + */ function onGlobalMouseUp() { IS_BUTTON_DOWN = false; } @@ -1119,6 +1322,6 @@ $.addEvent( window, "mousedown", onGlobalMouseDown, true ); $.addEvent( window, "mouseup", onGlobalMouseUp, true ); } - })(); + } )(); -}( OpenSeadragon )); +} ( OpenSeadragon ) ); diff --git a/src/navigator.js b/src/navigator.js index cd64f953..7197776a 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -251,13 +251,13 @@ $.extend( $.Navigator.prototype, $.EventHandler.prototype, $.Viewer.prototype, { * @inner * @function */ -function onCanvasClick( tracker, position, quick, shift ) { +function onCanvasClick( tracker, eventData ) { var newBounds, viewerPosition, dimensions; if (! this.drag) { if ( this.viewer.viewport ) { - viewerPosition = this.viewport.deltaPointsFromPixels(position); + viewerPosition = this.viewport.deltaPointsFromPixels( eventData.position ); dimensions = this.viewer.viewport.getBounds().getSize(); newBounds = new $.Rect( viewerPosition.x - dimensions.x/2, @@ -285,18 +285,18 @@ function onCanvasClick( tracker, position, quick, shift ) { * @inner * @function */ -function onCanvasDrag( tracker, position, delta, shift ) { +function onCanvasDrag( tracker, eventData ) { if ( this.viewer.viewport ) { this.drag = true; if( !this.panHorizontal ){ - delta.x = 0; + eventData.delta.x = 0; } if( !this.panVertical ){ - delta.y = 0; + eventData.delta.y = 0; } this.viewer.viewport.panBy( this.viewport.deltaPointsFromPixels( - delta + eventData.delta ) ); } @@ -308,8 +308,8 @@ function onCanvasDrag( tracker, position, delta, shift ) { * @inner * @function */ -function onCanvasRelease( tracker, position, insideElementPress, insideElementRelease ) { - if ( insideElementPress && this.viewer.viewport ) { +function onCanvasRelease( tracker, eventData ) { + if ( eventData.insideElementPressed && this.viewer.viewport ) { this.viewer.viewport.applyConstraints(); } } diff --git a/src/openseadragon.js b/src/openseadragon.js index e2743779..4e63fd22 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -699,6 +699,44 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ }, + /** + * Determines the position of the upper-left corner of the element adjusted for current page and/or element scroll. + * @function + * @name OpenSeadragon.getElementOffset + * @param {Element|String} element - the element we want the position for. + * @returns {Point} - the position of the upper left corner of the element adjusted for current page and/or element scroll. + */ + getElementOffset: function( element ) { + element = $.getElement( element ); + + var doc = element && element.ownerDocument, + docElement, + win, + boundingRect = { top: 0, left: 0 }; + + if ( !doc ) { + return new $.Point(); + } + + docElement = doc.documentElement; + + if ( typeof element.getBoundingClientRect !== typeof undefined ) { + boundingRect = element.getBoundingClientRect(); + } + + win = ( doc == doc.window ) ? + doc : + ( doc.nodeType === 9 ) ? + doc.defaultView || doc.parentWindow : + false; + + return new $.Point( + boundingRect.left + ( win.pageXOffset || docElement.scrollLeft ) - ( docElement.clientLeft || 0 ), + boundingRect.top + ( win.pageYOffset || docElement.scrollTop ) - ( docElement.clientTop || 0 ) + ); + }, + + /** * Determines the height and width of the given element. * @function diff --git a/src/referencestrip.js b/src/referencestrip.js index cfa053da..47e7cf46 100644 --- a/src/referencestrip.js +++ b/src/referencestrip.js @@ -32,7 +32,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -(function( $ ){ +(function ( $ ) { // dictionary from id to private properties var THIS = {}; @@ -56,7 +56,7 @@ var THIS = {}; * require better abstraction at those points in order to effeciently * reuse those paradigms. */ -$.ReferenceStrip = function( options ){ +$.ReferenceStrip = function ( options ) { var _this = this, viewer = options.viewer, @@ -67,7 +67,7 @@ $.ReferenceStrip = function( options ){ //We may need to create a new element and id if they did not //provide the id for the existing element - if( !options.id ){ + if ( !options.id ) { options.id = 'referencestrip-' + $.now(); this.element = $.makeNeutralElement( "div" ); this.element.id = options.id; @@ -88,17 +88,17 @@ $.ReferenceStrip = function( options ){ mouseNavEnabled: false, showNavigationControl: false, showSequenceControl: false - }); + } ); $.extend( this, options ); //Private state properties - THIS[ this.id ] = { - "animating": false + THIS[this.id] = { + "animating": false }; this.minPixelRatio = this.viewer.minPixelRatio; - style = this.element.style; + style = this.element.style; style.marginTop = '0px'; style.marginRight = '0px'; style.marginBottom = '0px'; @@ -112,56 +112,56 @@ $.ReferenceStrip = function( options ){ $.setElementOpacity( this.element, 0.8 ); this.viewer = viewer; - this.innerTracker = new $.MouseTracker({ + this.innerTracker = new $.MouseTracker( { element: this.element, dragHandler: $.delegate( this, onStripDrag ), scrollHandler: $.delegate( this, onStripScroll ), enterHandler: $.delegate( this, onStripEnter ), exitHandler: $.delegate( this, onStripExit ), keyHandler: $.delegate( this, onKeyPress ) - }).setTracking( true ); + } ).setTracking( true ); //Controls the position and orientation of the reference strip and sets the //appropriate width and height - if( options.width && options.height ){ + if ( options.width && options.height ) { this.element.style.width = options.width + 'px'; this.element.style.height = options.height + 'px'; viewer.addControl( this.element, - {anchor: $.ControlAnchor.BOTTOM_LEFT} + { anchor: $.ControlAnchor.BOTTOM_LEFT } ); } else { - if( "horizontal" == options.scroll ){ + if ( "horizontal" == options.scroll ) { this.element.style.width = ( viewerSize.x * options.sizeRatio * viewer.tileSources.length ) + ( 12 * viewer.tileSources.length ) + 'px'; - this.element.style.height = ( + this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px'; viewer.addControl( this.element, - {anchor: $.ControlAnchor.BOTTOM_LEFT} + { anchor: $.ControlAnchor.BOTTOM_LEFT } ); - }else { + } else { this.element.style.height = ( viewerSize.y * options.sizeRatio * viewer.tileSources.length ) + ( 12 * viewer.tileSources.length ) + 'px'; - this.element.style.width = ( + this.element.style.width = ( viewerSize.x * options.sizeRatio ) + 'px'; viewer.addControl( this.element, - {anchor: $.ControlAnchor.TOP_LEFT} + { anchor: $.ControlAnchor.TOP_LEFT } ); } @@ -172,9 +172,9 @@ $.ReferenceStrip = function( options ){ this.panels = []; /*jshint loopfunc:true*/ - for( i = 0; i < viewer.tileSources.length; i++ ){ + for ( i = 0; i < viewer.tileSources.length; i++ ) { - element = $.makeNeutralElement('div'); + element = $.makeNeutralElement( 'div' ); element.id = this.element.id + "-" + i; element.style.width = _this.panelWidth + 'px'; @@ -185,27 +185,27 @@ $.ReferenceStrip = function( options ){ element.style.styleFloat = 'left'; //IE element.style.padding = '2px'; - element.innerTracker = new $.MouseTracker({ + element.innerTracker = new $.MouseTracker( { element: element, clickTimeThreshold: this.clickTimeThreshold, clickDistThreshold: this.clickDistThreshold, - pressHandler: function( tracker ){ + pressHandler: function ( tracker, eventData ) { tracker.dragging = $.now(); }, - releaseHandler: function( tracker, position, insideElementPress, insideElementRelease ){ - var id = tracker.element.id, - page = Number( id.split( '-' )[ 2 ] ), - now = $.now(); + releaseHandler: function ( tracker, eventData ) { + var id = tracker.element.id, + page = Number( id.split( '-' )[2] ), + now = $.now(); - if ( insideElementPress && - insideElementRelease && + if ( eventData.insideElementPressed && + eventData.insideElementReleased && tracker.dragging && - ( now - tracker.dragging ) < tracker.clickTimeThreshold ){ + ( now - tracker.dragging ) < tracker.clickTimeThreshold ) { tracker.dragging = null; viewer.goToPage( page ); } } - }).setTracking( true ); + } ).setTracking( true ); this.element.appendChild( element ); @@ -214,49 +214,49 @@ $.ReferenceStrip = function( options ){ this.panels.push( element ); } - loadPanels( this, this.scroll == 'vertical' ? viewerSize.y : viewerSize.y, 0); + loadPanels( this, this.scroll == 'vertical' ? viewerSize.y : viewerSize.y, 0 ); this.setFocus( 0 ); }; $.extend( $.ReferenceStrip.prototype, $.EventHandler.prototype, $.Viewer.prototype, { - setFocus: function( page ){ - var element = $.getElement( this.element.id + '-' + page ), - viewerSize = $.getElementSize( this.viewer.canvas ), - scrollWidth = Number(this.element.style.width.replace('px','')), - scrollHeight = Number(this.element.style.height.replace('px','')), - offsetLeft = -Number(this.element.style.marginLeft.replace('px','')), - offsetTop = -Number(this.element.style.marginTop.replace('px','')), + setFocus: function ( page ) { + var element = $.getElement( this.element.id + '-' + page ), + viewerSize = $.getElementSize( this.viewer.canvas ), + scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), + scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), + offsetLeft = -Number( this.element.style.marginLeft.replace( 'px', '' ) ), + offsetTop = -Number( this.element.style.marginTop.replace( 'px', '' ) ), offset; - if ( this.currentSelected !== element ){ - if( this.currentSelected ){ + if ( this.currentSelected !== element ) { + if ( this.currentSelected ) { this.currentSelected.style.background = '#000'; } this.currentSelected = element; this.currentSelected.style.background = '#999'; - if( 'horizontal' == this.scroll ){ + if ( 'horizontal' == this.scroll ) { //right left - offset = (Number(page)) * ( this.panelWidth + 3 ); - if( offset > offsetLeft + viewerSize.x - this.panelWidth){ - offset = Math.min(offset, (scrollWidth - viewerSize.x)); + offset = ( Number( page ) ) * ( this.panelWidth + 3 ); + if ( offset > offsetLeft + viewerSize.x - this.panelWidth ) { + offset = Math.min( offset, ( scrollWidth - viewerSize.x ) ); this.element.style.marginLeft = -offset + 'px'; loadPanels( this, viewerSize.x, -offset ); - }else if( offset < offsetLeft ){ - offset = Math.max(0, offset - viewerSize.x / 2); + } else if ( offset < offsetLeft ) { + offset = Math.max( 0, offset - viewerSize.x / 2 ); this.element.style.marginLeft = -offset + 'px'; loadPanels( this, viewerSize.x, -offset ); } - }else{ - offset = (Number(page) ) * ( this.panelHeight + 3 ); - if( offset > offsetTop + viewerSize.y - this.panelHeight){ - offset = Math.min(offset, (scrollHeight - viewerSize.y)); + } else { + offset = ( Number( page ) ) * ( this.panelHeight + 3 ); + if ( offset > offsetTop + viewerSize.y - this.panelHeight ) { + offset = Math.min( offset, ( scrollHeight - viewerSize.y ) ); this.element.style.marginTop = -offset + 'px'; loadPanels( this, viewerSize.y, -offset ); - }else if( offset < offsetTop ){ - offset = Math.max(0, offset - viewerSize.y / 2); + } else if ( offset < offsetTop ) { + offset = Math.max( 0, offset - viewerSize.y / 2 ); this.element.style.marginTop = -offset + 'px'; loadPanels( this, viewerSize.y, -offset ); } @@ -264,22 +264,22 @@ $.extend( $.ReferenceStrip.prototype, $.EventHandler.prototype, $.Viewer.prototy this.currentPage = page; $.getElement( element.id + '-displayregion' ).focus(); - onStripEnter.call( this, this.innerTracker ); + onStripEnter.call( this, this.innerTracker, {} ); } }, /** * @function * @name OpenSeadragon.ReferenceStrip.prototype.update */ - update: function() { - if ( THIS[ this.id ].animating ) { - $.console.log('image reference strip update'); + update: function () { + if ( THIS[this.id].animating ) { + $.console.log( 'image reference strip update' ); return true; } return false; } -}); +} ); @@ -289,41 +289,41 @@ $.extend( $.ReferenceStrip.prototype, $.EventHandler.prototype, $.Viewer.prototy * @inner * @function */ -function onStripDrag( tracker, position, delta, shift ) { +function onStripDrag( tracker, eventData ) { - var offsetLeft = Number(this.element.style.marginLeft.replace('px','')), - offsetTop = Number(this.element.style.marginTop.replace('px','')), - scrollWidth = Number(this.element.style.width.replace('px','')), - scrollHeight = Number(this.element.style.height.replace('px','')), - viewerSize = $.getElementSize( this.viewer.canvas ); + var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ), + offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ), + scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), + scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), + viewerSize = $.getElementSize( this.viewer.canvas ); this.dragging = true; if ( this.element ) { - if( 'horizontal' == this.scroll ){ - if ( -delta.x > 0 ) { + if ( 'horizontal' == this.scroll ) { + if ( -eventData.delta.x > 0 ) { //forward - if( offsetLeft > -(scrollWidth - viewerSize.x)){ - this.element.style.marginLeft = ( offsetLeft + (delta.x * 2) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft + (delta.x * 2) ); + if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) { + this.element.style.marginLeft = ( offsetLeft + ( eventData.delta.x * 2 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft + ( eventData.delta.x * 2 ) ); } - } else if ( -delta.x < 0 ) { + } else if ( -eventData.delta.x < 0 ) { //reverse - if( offsetLeft < 0 ){ - this.element.style.marginLeft = ( offsetLeft + (delta.x * 2) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft + (delta.x * 2) ); + if ( offsetLeft < 0 ) { + this.element.style.marginLeft = ( offsetLeft + ( eventData.delta.x * 2 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft + ( eventData.delta.x * 2 ) ); } } - }else{ - if ( -delta.y > 0 ) { + } else { + if ( -eventData.delta.y > 0 ) { //forward - if( offsetTop > -(scrollHeight - viewerSize.y)){ - this.element.style.marginTop = ( offsetTop + (delta.y * 2) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + (delta.y * 2) ); + if ( offsetTop > -( scrollHeight - viewerSize.y ) ) { + this.element.style.marginTop = ( offsetTop + ( eventData.delta.y * 2 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.delta.y * 2 ) ); } - } else if ( -delta.y < 0 ) { + } else if ( -eventData.delta.y < 0 ) { //reverse - if( offsetTop < 0 ){ - this.element.style.marginTop = ( offsetTop + (delta.y * 2) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + (delta.y * 2) ); + if ( offsetTop < 0 ) { + this.element.style.marginTop = ( offsetTop + ( eventData.delta.y * 2 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.delta.y * 2 ) ); } } } @@ -339,39 +339,39 @@ function onStripDrag( tracker, position, delta, shift ) { * @inner * @function */ -function onStripScroll( tracker, position, scroll, shift ) { - var offsetLeft = Number(this.element.style.marginLeft.replace('px','')), - offsetTop = Number(this.element.style.marginTop.replace('px','')), - scrollWidth = Number(this.element.style.width.replace('px','')), - scrollHeight = Number(this.element.style.height.replace('px','')), - viewerSize = $.getElementSize( this.viewer.canvas ); +function onStripScroll( tracker, eventData ) { + var offsetLeft = Number( this.element.style.marginLeft.replace( 'px', '' ) ), + offsetTop = Number( this.element.style.marginTop.replace( 'px', '' ) ), + scrollWidth = Number( this.element.style.width.replace( 'px', '' ) ), + scrollHeight = Number( this.element.style.height.replace( 'px', '' ) ), + viewerSize = $.getElementSize( this.viewer.canvas ); if ( this.element ) { - if( 'horizontal' == this.scroll ){ - if ( scroll > 0 ) { + if ( 'horizontal' == this.scroll ) { + if ( eventData.scroll > 0 ) { //forward - if( offsetLeft > -(scrollWidth - viewerSize.x)){ - this.element.style.marginLeft = ( offsetLeft - (scroll * 60) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft - (scroll * 60) ); + if ( offsetLeft > -( scrollWidth - viewerSize.x ) ) { + this.element.style.marginLeft = ( offsetLeft - ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft - ( eventData.scroll * 60 ) ); } - } else if ( scroll < 0 ) { + } else if ( eventData.scroll < 0 ) { //reverse - if( offsetLeft < 0 ){ - this.element.style.marginLeft = ( offsetLeft - (scroll * 60) ) + 'px'; - loadPanels( this, viewerSize.x, offsetLeft - (scroll * 60) ); + if ( offsetLeft < 0 ) { + this.element.style.marginLeft = ( offsetLeft - ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.x, offsetLeft - ( eventData.scroll * 60 ) ); } } - }else{ - if ( scroll < 0 ) { + } else { + if ( eventData.scroll < 0 ) { //scroll up - if( offsetTop > viewerSize.y - scrollHeight ){ - this.element.style.marginTop = ( offsetTop + (scroll * 60) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + (scroll * 60) ); + if ( offsetTop > viewerSize.y - scrollHeight ) { + this.element.style.marginTop = ( offsetTop + ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.scroll * 60 ) ); } - } else if ( scroll > 0 ) { + } else if ( eventData.scroll > 0 ) { //scroll dowm - if( offsetTop < 0 ){ - this.element.style.marginTop = ( offsetTop + (scroll * 60) ) + 'px'; - loadPanels( this, viewerSize.y, offsetTop + (scroll * 60) ); + if ( offsetTop < 0 ) { + this.element.style.marginTop = ( offsetTop + ( eventData.scroll * 60 ) ) + 'px'; + loadPanels( this, viewerSize.y, offsetTop + ( eventData.scroll * 60 ) ); } } } @@ -381,7 +381,7 @@ function onStripScroll( tracker, position, scroll, shift ) { } -function loadPanels(strip, viewerSize, scroll){ +function loadPanels( strip, viewerSize, scroll ) { var panelSize, activePanelsStart, activePanelsEnd, @@ -389,22 +389,22 @@ function loadPanels(strip, viewerSize, scroll){ style, i, element; - if( 'horizontal' == strip.scroll ){ + if ( 'horizontal' == strip.scroll ) { panelSize = strip.panelWidth; - }else{ + } else { panelSize = strip.panelHeight; } activePanelsStart = Math.ceil( viewerSize / panelSize ) + 5; - activePanelsEnd = Math.ceil( (Math.abs(scroll) + viewerSize ) / panelSize ) + 1; + activePanelsEnd = Math.ceil( ( Math.abs( scroll ) + viewerSize ) / panelSize ) + 1; activePanelsStart = activePanelsEnd - activePanelsStart; activePanelsStart = activePanelsStart < 0 ? 0 : activePanelsStart; - for( i = activePanelsStart; i < activePanelsEnd && i < strip.panels.length; i++ ){ - element = strip.panels[ i ]; - if ( !element.activePanel ){ + for ( i = activePanelsStart; i < activePanelsEnd && i < strip.panels.length; i++ ) { + element = strip.panels[i]; + if ( !element.activePanel ) { miniViewer = new $.Viewer( { id: element.id, - tileSources: [ strip.viewer.tileSources[ i ] ], + tileSources: [strip.viewer.tileSources[i]], element: element, navigatorSizeRatio: strip.sizeRatio, showNavigator: false, @@ -420,7 +420,7 @@ function loadPanels(strip, viewerSize, scroll){ miniViewer.displayRegion.id = element.id + '-displayregion'; miniViewer.displayRegion.className = 'displayregion'; - style = miniViewer.displayRegion.style; + style = miniViewer.displayRegion.style; style.position = 'relative'; style.top = '0px'; style.left = '0px'; @@ -434,11 +434,11 @@ function loadPanels(strip, viewerSize, scroll){ style.width = ( strip.panelWidth - 4 ) + 'px'; style.height = ( strip.panelHeight - 4 ) + 'px'; - miniViewer.displayRegion.innerTracker = new $.MouseTracker({ - element: miniViewer.displayRegion - }); + miniViewer.displayRegion.innerTracker = new $.MouseTracker( { + element: miniViewer.displayRegion + } ); - element.getElementsByTagName('form')[ 0 ].appendChild( + element.getElementsByTagName( 'form' )[0].appendChild( miniViewer.displayRegion ); @@ -453,14 +453,14 @@ function loadPanels(strip, viewerSize, scroll){ * @inner * @function */ -function onStripEnter( tracker ) { +function onStripEnter( tracker, eventData ) { //$.setElementOpacity(tracker.element, 0.8); //tracker.element.style.border = '1px solid #555'; //tracker.element.style.background = '#000'; - if( 'horizontal' == this.scroll ){ + if ( 'horizontal' == this.scroll ) { //tracker.element.style.paddingTop = "0px"; tracker.element.style.marginBottom = "0px"; @@ -480,7 +480,7 @@ function onStripEnter( tracker ) { * @inner * @function */ -function onStripExit( tracker ) { +function onStripExit( tracker, eventData ) { if ( 'horizontal' == this.scroll ) { //tracker.element.style.paddingTop = "10px"; @@ -489,7 +489,7 @@ function onStripExit( tracker ) { } else { //tracker.element.style.paddingRight = "10px"; - tracker.element.style.marginLeft = "-" + ( $.getElementSize( tracker.element ).x / 2 )+ "px"; + tracker.element.style.marginLeft = "-" + ( $.getElementSize( tracker.element ).x / 2 ) + "px"; } return false; @@ -502,41 +502,41 @@ function onStripExit( tracker ) { * @inner * @function */ -function onKeyPress( tracker, keyCode, shiftKey ){ - //console.log( keyCode ); +function onKeyPress( tracker, eventData ) { + //console.log( eventData.keyCode ); - switch( keyCode ){ - case 61://=|+ - onStripScroll.call(this, this.tracker, null, 1, null); + switch ( eventData.keyCode ) { + case 61: //=|+ + onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); return false; - case 45://-|_ - onStripScroll.call(this, this.tracker, null, -1, null); + case 45: //-|_ + onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); return false; - case 48://0|) - case 119://w - case 87://W - case 38://up arrow - onStripScroll.call(this, this.tracker, null, 1, null); + case 48: //0|) + case 119: //w + case 87: //W + case 38: //up arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); return false; - case 115://s - case 83://S - case 40://down arrow - onStripScroll.call(this, this.tracker, null, -1, null); + case 115: //s + case 83: //S + case 40: //down arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); return false; - case 97://a - case 37://left arrow - onStripScroll.call(this, this.tracker, null, -1, null); + case 97: //a + case 37: //left arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: -1, shift: null } ); return false; - case 100://d - case 39://right arrow - onStripScroll.call(this, this.tracker, null, 1, null); + case 100: //d + case 39: //right arrow + onStripScroll.call( this, this.tracker, { position: null, scroll: 1, shift: null } ); return false; default: - //console.log( 'navigator keycode %s', keyCode ); + //console.log( 'navigator keycode %s', eventData.keyCode ); return true; } } -}( OpenSeadragon )); +} ( OpenSeadragon ) ); diff --git a/src/viewer.js b/src/viewer.js index f1880afc..56a0a2c1 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -265,8 +265,8 @@ $.Viewer = function( options ) { window.scrollTo( 0, point.y ); }, - keyHandler: function(tracker, keyCode, shiftKey){ - switch( keyCode ){ + keyHandler: function( tracker, eventData ){ + switch( eventData.keyCode ){ case 61://=|+ _this.viewport.zoomBy(1.1); _this.viewport.applyConstraints(); @@ -282,7 +282,7 @@ $.Viewer = function( options ) { case 119://w case 87://W case 38://up arrow - if (shiftKey) { + if ( eventData.shift ) { _this.viewport.zoomBy(1.1); } else { _this.viewport.panBy(new $.Point(0, -0.05)); @@ -292,7 +292,7 @@ $.Viewer = function( options ) { case 115://s case 83://S case 40://down arrow - if (shiftKey) { + if ( eventData.shift ) { _this.viewport.zoomBy(0.9); } else { _this.viewport.panBy(new $.Point(0, 0.05)); @@ -310,7 +310,7 @@ $.Viewer = function( options ) { _this.viewport.applyConstraints(); return false; default: - //console.log( 'navigator keycode %s', keyCode ); + //console.log( 'navigator keycode %s', eventData.keyCode ); return true; } } @@ -511,7 +511,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, return this; }, - + /** * Function to destroy the viewer and clean up everything created by * OpenSeadragon. @@ -666,7 +666,8 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, this.previousBody = []; THIS[ this.hash ].prevElementParent = this.element.parentNode; THIS[ this.hash ].prevNextSibling = this.element.nextSibling; - THIS[ this.hash ].prevElementSize = $.getElementSize( this.element ); + THIS[ this.hash ].prevElementWidth = this.element.style.width; + THIS[ this.hash ].prevElementHeight = this.element.style.height; nodes = body.childNodes.length; for ( i = 0; i < nodes; i ++ ){ this.previousBody.push( body.childNodes[ 0 ] ); @@ -730,7 +731,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, THIS[ this.hash ].fullPage = true; // mouse will be inside container now - $.delegate( this, onContainerEnter )(); + $.delegate( this, onContainerEnter )( null, {} ); } else { @@ -783,13 +784,13 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype, //this.container.style.top = 'auto'; } - this.element.style.height = THIS[ this.hash ].prevElementSize.y + 'px'; - this.element.style.width = THIS[ this.hash ].prevElementSize.x + 'px'; + this.element.style.width = THIS[ this.hash ].prevElementWidth; + this.element.style.height = THIS[ this.hash ].prevElementHeight; THIS[ this.hash ].fullPage = false; // mouse will likely be outside now - $.delegate( this, onContainerExit )(); + $.delegate( this, onContainerExit )( null, {} ); } @@ -1426,37 +1427,37 @@ function onBlur(){ } -function onCanvasClick( tracker, position, quick, shift ) { +function onCanvasClick( tracker, eventData ) { var zoomPerClick, factor; - if ( this.viewport && quick ) { // ignore clicks where mouse moved + if ( this.viewport && eventData.quick ) { // ignore clicks where mouse moved zoomPerClick = this.zoomPerClick; - factor = shift ? 1.0 / zoomPerClick : zoomPerClick; + factor = eventData.shift ? 1.0 / zoomPerClick : zoomPerClick; this.viewport.zoomBy( factor, - this.viewport.pointFromPixel( position, true ) + this.viewport.pointFromPixel( eventData.position, true ) ); this.viewport.applyConstraints(); } this.raiseEvent( 'canvas-click', { tracker: tracker, - position: position, - quick: quick, - shift: shift + position: eventData.position, + quick: eventData.quick, + shift: eventData.shift }); } -function onCanvasDrag( tracker, position, delta, shift ) { +function onCanvasDrag( tracker, eventData ) { if ( this.viewport ) { if( !this.panHorizontal ){ - delta.x = 0; + eventData.delta.x = 0; } if( !this.panVertical ){ - delta.y = 0; + eventData.delta.y = 0; } this.viewport.panBy( this.viewport.deltaPointsFromPixels( - delta.negate() + eventData.delta.negate() ) ); if( this.constrainDuringPan ){ @@ -1465,46 +1466,46 @@ function onCanvasDrag( tracker, position, delta, shift ) { } this.raiseEvent( 'canvas-drag', { tracker: tracker, - position: position, - delta: delta, - shift: shift + position: eventData.position, + delta: eventData.delta, + shift: eventData.shift }); } -function onCanvasRelease( tracker, position, insideElementPress, insideElementRelease ) { - if ( insideElementPress && this.viewport ) { +function onCanvasRelease( tracker, eventData ) { + if ( eventData.insideElementPressed && this.viewport ) { this.viewport.applyConstraints(); } this.raiseEvent( 'canvas-release', { tracker: tracker, - position: position, - insideElementPress: insideElementPress, - insideElementRelease: insideElementRelease + position: eventData.position, + insideElementPressed: eventData.insideElementPressed, + insideElementReleased: eventData.insideElementReleased }); } -function onCanvasScroll( tracker, position, scroll, shift ) { +function onCanvasScroll( tracker, eventData ) { var factor; if ( this.viewport ) { - factor = Math.pow( this.zoomPerScroll, scroll ); + factor = Math.pow( this.zoomPerScroll, eventData.scroll ); this.viewport.zoomBy( factor, - this.viewport.pointFromPixel( position, true ) + this.viewport.pointFromPixel( eventData.position, true ) ); this.viewport.applyConstraints(); } this.raiseEvent( 'canvas-scroll', { tracker: tracker, - position: position, - scroll: scroll, - shift: shift + position: eventData.position, + scroll: eventData.scroll, + shift: eventData.shift }); //cancels event return false; } -function onContainerExit( tracker, position, buttonDownElement, buttonDownAny ) { - if ( !buttonDownElement ) { +function onContainerExit( tracker, eventData ) { + if ( !eventData.insideElementPressed ) { THIS[ this.hash ].mouseInside = false; if ( !THIS[ this.hash ].animating ) { beginControlsAutoHide( this ); @@ -1512,14 +1513,14 @@ function onContainerExit( tracker, position, buttonDownElement, buttonDownAny ) } this.raiseEvent( 'container-exit', { tracker: tracker, - position: position, - buttonDownElement: buttonDownElement, - buttonDownAny: buttonDownAny + position: eventData.position, + insideElementPressed: eventData.insideElementPressed, + buttonDownAny: eventData.buttonDownAny }); } -function onContainerRelease( tracker, position, insideElementPress, insideElementRelease ) { - if ( !insideElementRelease ) { +function onContainerRelease( tracker, eventData ) { + if ( !eventData.insideElementReleased ) { THIS[ this.hash ].mouseInside = false; if ( !THIS[ this.hash ].animating ) { beginControlsAutoHide( this ); @@ -1527,20 +1528,20 @@ function onContainerRelease( tracker, position, insideElementPress, insideElemen } this.raiseEvent( 'container-release', { tracker: tracker, - position: position, - insideElementPress: insideElementPress, - insideElementRelease: insideElementRelease + position: eventData.position, + insideElementPressed: eventData.insideElementPressed, + insideElementReleased: eventData.insideElementReleased }); } -function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) { +function onContainerEnter( tracker, eventData ) { THIS[ this.hash ].mouseInside = true; abortControlsAutoHide( this ); this.raiseEvent( 'container-enter', { tracker: tracker, - position: position, - buttonDownElement: buttonDownElement, - buttonDownAny: buttonDownAny + position: eventData.position, + insideElementPressed: eventData.insideElementPressed, + buttonDownAny: eventData.buttonDownAny }); } diff --git a/test/events.js b/test/events.js index b2e71eb6..c7608711 100644 --- a/test/events.js +++ b/test/events.js @@ -61,19 +61,49 @@ } ); // ---------- - asyncTest( 'canvas-drag canvas-release canvas-click', function () { - var dragCount = 10, - dragMovesHandled = 0, - releasesHandled = 0, - releasesExpected = 1; + asyncTest( 'MouseTracker, EventHandler canvas-drag canvas-release canvas-click', function () { + var $canvas = $( viewer.element ).find( '.openseadragon-canvas' ).not( '.navigator .openseadragon-canvas' ), + mouseTracker = null, + userData = { item1: 'Test user data', item2: Math.random() }, + originalUserData = { item1: userData.item1, item2: userData.item2 }, + dragCount = 10, + dragsHandledEventHandler = 0, + releasesHandledEventHandler = 0, + clicksHandledEventHandler = 0, + eventsHandledMouseTracker = 0, + originalEventsPassedMouseTracker = 0, + releasesExpected = 1, + clicksExpected = 1; - var openHandler = function ( eventSender, eventData ) { - viewer.removeHandler( 'open', openHandler ); + var onOpen = function ( eventSender, eventData ) { + viewer.removeHandler( 'open', onOpen ); - viewer.addHandler( 'canvas-drag', canvasDragHandler ); - viewer.addHandler( 'canvas-release', canvasReleaseHandler ); - viewer.addHandler( 'canvas-click', canvasClickHandler ); + viewer.addHandler( 'canvas-drag', onEventHandlerDrag ); + viewer.addHandler( 'canvas-release', onEventHandlerRelease ); + viewer.addHandler( 'canvas-click', onEventHandlerClick ); + mouseTracker = new OpenSeadragon.MouseTracker( { + element: $canvas[0], + userData: userData, + clickTimeThreshold: OpenSeadragon.DEFAULT_SETTINGS.clickTimeThreshold, + clickDistThreshold: OpenSeadragon.DEFAULT_SETTINGS.clickDistThreshold, + focusHandler: onMouseTrackerFocus, + blurHandler: onMouseTrackerBlur, + enterHandler: onMouseTrackerEnter, + pressHandler: onMouseTrackerPress, + moveHandler: onMouseTrackerMove, + dragHandler: onMouseTrackerDrag, + releaseHandler: onMouseTrackerRelease, + clickHandler: onMouseTrackerClick, + exitHandler: onMouseTrackerExit + } ).setTracking( true ); + + var event = { + clientX:1, + clientY:1 + }; + + $canvas.simulate( 'focus', event ); Util.simulateViewerClickWithDrag( { viewer: viewer, widthFactor: 0.25, @@ -82,27 +112,80 @@ dragDx: 1, dragDy: 1 } ); + $canvas.simulate( 'blur', event ); }; - var canvasDragHandler = function ( eventSender, eventData ) { - dragMovesHandled++; + var onEventHandlerDrag = function ( eventSender, eventData ) { + dragsHandledEventHandler++; }; - var canvasReleaseHandler = function ( eventSender, eventData ) { - releasesHandled++; + var onEventHandlerRelease = function ( eventSender, eventData ) { + releasesHandledEventHandler++; }; - var canvasClickHandler = function ( eventSender, eventData ) { - viewer.removeHandler( 'canvas-drag', canvasDragHandler ); - viewer.removeHandler( 'canvas-release', canvasReleaseHandler ); - viewer.removeHandler( 'canvas-click', canvasClickHandler ); - equal( dragMovesHandled, dragCount, "'canvas-drag' event count matches 'mousemove' event count (" + dragCount + ")" ); - equal( releasesHandled, releasesExpected, "'canvas-release' event count matches expected (" + releasesExpected + ")" ); + var onEventHandlerClick = function ( eventSender, eventData ) { + clicksHandledEventHandler++; + }; + + var checkOriginalEventReceived = function ( eventData ) { + eventsHandledMouseTracker++; + if ( eventData && eventData.originalEvent ) { + originalEventsPassedMouseTracker++; + } + }; + + var onMouseTrackerFocus = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerBlur = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerEnter = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerPress = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerMove = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerDrag = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerRelease = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerClick = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + }; + + var onMouseTrackerExit = function ( tracker, eventData ) { + checkOriginalEventReceived( eventData ); + + mouseTracker.destroy(); + viewer.removeHandler( 'canvas-drag', onEventHandlerDrag ); + viewer.removeHandler( 'canvas-release', onEventHandlerRelease ); + viewer.removeHandler( 'canvas-click', onEventHandlerClick ); + + equal( dragsHandledEventHandler, dragCount, "'canvas-drag' event count matches 'mousemove' event count (" + dragCount + ")" ); + equal( releasesHandledEventHandler, releasesExpected, "'canvas-release' event count matches expected (" + releasesExpected + ")" ); + equal( clicksHandledEventHandler, releasesExpected, "'canvas-click' event count matches expected (" + releasesExpected + ")" ); + + equal( originalEventsPassedMouseTracker, eventsHandledMouseTracker, "Original event received count matches expected (" + eventsHandledMouseTracker + ")" ); + deepEqual( eventData.userData, originalUserData, 'MouseTracker userData was untouched' ); + viewer.close(); start(); }; - viewer.addHandler( 'open', openHandler ); + viewer.addHandler( 'open', onOpen ); viewer.open( '/test/data/testpattern.dzi' ); } ); diff --git a/test/test.js b/test/test.js index def55713..2272ea9d 100644 --- a/test/test.js +++ b/test/test.js @@ -46,7 +46,8 @@ .simulate( "mousemove", event ); } $canvas - .simulate( 'mouseup', event ); + .simulate( 'mouseup', event ) + .simulate( 'mouseout', event ); }, initializeTestDOM: function () {