initial attempt at cleaning up events in terms of where they are raised, how they affect default behavior, and how the affect other handlers. I need to do another pass because its clear that we want to be able to independently prevent default and stop propagation just like normal javascript events

This commit is contained in:
thatcher 2013-03-08 20:27:08 -05:00
parent 6285a779f3
commit 3d2fb54ea3
4 changed files with 201 additions and 165 deletions

View File

@ -133,25 +133,31 @@ $.Drawer.prototype = {
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the
* viewport which the location coordinates will be treated as relative
* to.
* @return {OpenSeadragon.Drawer} Chainable.
*/
addOverlay: function( element, location, placement ) {
var stop;
element = $.getElement( element );
if ( getOverlayIndex( this.overlays, element ) >= 0 ) {
// they're trying to add a duplicate overlay
return;
}
this.overlays.push( new $.Overlay( element, location, placement ) );
this.updateAgain = true;
if( this.viewer ){
this.viewer.raiseEvent( 'add-overlay', {
stop = this.viewer.raiseEvent( 'addoverlay', {
viewer: this.viewer,
element: element,
location: location,
placement: placement
});
if( false === stop ){
return this;
}
}
if ( getOverlayIndex( this.overlays, element ) >= 0 ) {
// they're trying to add a duplicate overlay
return this;
}
this.overlays.push( new $.Overlay( element, location, placement ) );
this.updateAgain = true;
return this;
},
@ -167,22 +173,27 @@ $.Drawer.prototype = {
* @return {OpenSeadragon.Drawer} Chainable.
*/
updateOverlay: function( element, location, placement ) {
var i;
var i,
stop;
element = $.getElement( element );
i = getOverlayIndex( this.overlays, element );
if ( i >= 0 ) {
this.overlays[ i ].update( location, placement );
this.updateAgain = true;
}
if( this.viewer ){
this.viewer.raiseEvent( 'update-overlay', {
stop = this.viewer.raiseEvent( 'updateoverlay', {
viewer: this.viewer,
element: element,
location: location,
placement: placement
});
if( false === stop ){
return this;
}
}
if ( i >= 0 ) {
this.overlays[ i ].update( location, placement );
this.updateAgain = true;
}
return this;
},
@ -201,17 +212,21 @@ $.Drawer.prototype = {
element = $.getElement( element );
i = getOverlayIndex( this.overlays, element );
if( this.viewer ){
stop = this.viewer.raiseEvent( 'removeoverlay', {
viewer: this.viewer,
element: element
});
if( false === stop ){
return this;
}
}
if ( i >= 0 ) {
this.overlays[ i ].destroy();
this.overlays.splice( i, 1 );
this.updateAgain = true;
}
if( this.viewer ){
this.viewer.raiseEvent( 'remove-overlay', {
viewer: this.viewer,
element: element
});
}
return this;
},
@ -222,15 +237,19 @@ $.Drawer.prototype = {
* @return {OpenSeadragon.Drawer} Chainable.
*/
clearOverlays: function() {
while ( this.overlays.length > 0 ) {
this.overlays.pop().destroy();
this.updateAgain = true;
}
var stop;
if( this.viewer ){
this.viewer.raiseEvent( 'clear-overlay', {
stop = this.viewer.raiseEvent( 'clearoverlay', {
viewer: this.viewer,
element: element
});
if( false === stop ){
return this;
}
}
while ( this.overlays.length > 0 ) {
this.overlays.pop().destroy();
this.updateAgain = true;
}
return this;
},
@ -412,12 +431,6 @@ function updateViewport( drawer ) {
drawer.updateAgain = false;
if( drawer.viewer ){
drawer.viewer.raiseEvent( 'update-viewport', {
viewer: drawer.viewer
});
}
var tile,
level,
best = null,
@ -571,20 +584,6 @@ function updateLevel( drawer, haveDrawn, level, levelOpacity, levelVisibility, v
viewportCenter = drawer.viewport.pixelFromPoint( drawer.viewport.getCenter() );
if( drawer.viewer ){
drawer.viewer.raiseEvent( 'update-level', {
viewer: drawer.viewer,
havedrawn: haveDrawn,
level: level,
opacity: levelOpacity,
visibility: levelVisibility,
topleft: viewportTopLeft,
bottomright: viewportBottomRight,
currenttime: currentTime,
best: best
});
}
//OK, a new drawing so do your calculations
tileTL = drawer.source.getTileAtPoint( level, viewportTL );
tileBR = drawer.source.getTileAtPoint( level, viewportBR );
@ -636,13 +635,6 @@ function updateTile( drawer, drawLevel, haveDrawn, x, y, level, levelOpacity, le
drawTile = drawLevel,
newbest;
if( drawer.viewer ){
drawer.viewer.raiseEvent( 'update-tile', {
viewer: drawer.viewer,
tile: tile
});
}
setCoverage( drawer.coverage, level, x, y, false );
if ( !tile.exists ) {
@ -1140,12 +1132,6 @@ function drawTiles( drawer, lastDrawn ){
}
}
if( drawer.viewer ){
drawer.viewer.raiseEvent( 'tile-drawn', {
viewer: drawer.viewer,
tile: tile
});
}
}
}

View File

@ -81,10 +81,14 @@ $.EventHandler.prototype = {
Array.apply( null, events );
return function( source, args ) {
var i,
length = events.length;
length = events.length,
stop;
for ( i = 0; i < length; i++ ) {
if( events[ i ] ){
events[ i ]( source, args );
if( $.isFunction( events[ i ] ) {
stop = events[ i ].apply( source, args );
if( stop === false ){
return stop;
}
}
}
};
@ -106,7 +110,7 @@ $.EventHandler.prototype = {
eventArgs = {};
}
handler( this, eventArgs );
return handler( this, eventArgs );
}
}
};

View File

@ -342,6 +342,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
overlay,
i;
if( false === this.raiseEvent( 'open', { source: source } ) ){
//cancel open
return this;
}
if ( this.source ) {
this.close( );
}
@ -506,8 +511,6 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
this.navigator.open( source );
}
this.raiseEvent( 'open', { source: source, viewer: this } );
return this;
},
@ -517,6 +520,10 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
* @return {OpenSeadragon.Viewer} Chainable.
*/
close: function ( ) {
if( false === this.raiseEvent( 'close' ) ){
//cancel close
return this;
}
if( this.drawer ){
this.drawer.clearOverlays();
@ -532,8 +539,6 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
VIEWERS[ this.hash ] = null;
delete VIEWERS[ this.hash ];
this.raiseEvent( 'close', { viewer: this } );
return this;
},
@ -553,8 +558,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
* @return {OpenSeadragon.Viewer} Chainable.
*/
setMouseNavEnabled: function( enabled ){
if( false === this.raiseEvent( enabled ? 'activate' : 'deactivate' ) ){
//cancel activation/deactivation of mouse/touch/keyboard interactive
return this;
}
this.innerTracker.setTracking( enabled );
this.raiseEvent( 'mouse-enabled', { enabled: enabled, viewer: this } );
return this;
},
@ -580,12 +588,15 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
* @return {OpenSeadragon.Viewer} Chainable.
*/
setControlsEnabled: function( enabled ) {
if( false === this.raiseEvent( enabled ? 'showcontrols' : 'hidecontrols' ) ){
//cancel show/hide of controls
return this;
}
if( enabled ){
abortControlsAutoHide( this );
} else {
beginControlsAutoHide( this );
}
this.raiseEvent( 'controls-enabled', { enabled: enabled, viewer: this } );
return this;
},
@ -622,6 +633,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
nodes,
i;
if( false === this.raiseEvent( fullPage ? 'maximize' : 'minimize' ) ){
//cancel maximize/minimize
return this;
}
//dont bother modifying the DOM if we are already in full page mode.
if ( fullPage == this.isFullPage() ) {
return;
@ -747,7 +763,6 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
$.delegate( this, onContainerExit )();
}
this.raiseEvent( 'fullpage', { fullpage: fullPage, viewer: this } );
if ( this.viewport ) {
oldBounds = this.viewport.getBounds();
@ -806,8 +821,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
* @return {OpenSeadragon.Viewer} Chainable.
*/
setVisible: function( visible ){
if( false === this.raiseEvent( visible ? 'show' : 'hide' ) ){
//cancel show/hide
return this;
}
this.container.style.visibility = visible ? "" : "hidden";
this.raiseEvent( 'visible', { visible: visible, viewer: this } );
return this;
},
@ -1026,9 +1044,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
* @return {OpenSeadragon.Viewer} Chainable.
*/
goToPage: function( page ){
//page is a 1 based index so normalize now
//page = page;
this.raiseEvent( 'page', { page: page, viewer: this } );
if( false === this.raiseEvent( 'page', { page: page }) ){
//cancel page change
return this;
}
if( this.tileSources.length > page ){
@ -1171,8 +1191,15 @@ function onBlur(){
function onCanvasClick( tracker, position, quick, shift, event ) {
var zoomPreClick,
factor;
if ( this.viewport && quick ) { // ignore clicks where mouse moved
factor,
stop = this.raiseEvent( 'click', {
tracker: tracker,
position: position,
quick: quick,
shift: shift,
originalEvent: event
});
if ( this.viewport && quick && stop !== false ) { // ignore clicks where mouse moved
zoomPerClick = this.zoomPerClick;
factor = shift ? 1.0 / zoomPerClick : zoomPerClick;
this.viewport.zoomBy(
@ -1181,17 +1208,17 @@ function onCanvasClick( tracker, position, quick, shift, event ) {
);
this.viewport.applyConstraints();
}
this.raiseEvent( 'click', {
tracker: tracker,
position: position,
quick: quick,
shift: shift,
originalEvent: event
});
}
function onCanvasDrag( tracker, position, delta, shift, event ) {
if ( this.viewport ) {
var stop = this.raiseEvent( 'drag', {
tracker: tracker,
position: position,
delta: delta,
shift: shift,
originalEvent: event
});
if ( this.viewport && stop !== false ) {
if( !this.panHorizontal ){
delta.x = 0;
}
@ -1207,91 +1234,91 @@ function onCanvasDrag( tracker, position, delta, shift, event ) {
this.viewport.applyConstraints();
}
}
this.raiseEvent( 'drag', {
tracker: tracker,
position: position,
delta: delta,
shift: shift,
originalEvent: event
});
}
function onCanvasRelease( tracker, position, insideElementPress, insideElementRelease, event ) {
if ( insideElementPress && this.viewport ) {
this.viewport.applyConstraints();
}
this.raiseEvent( 'release', {
var stop = this.raiseEvent( 'release', {
tracker: tracker,
position: position,
insideElementPress: insideElementPress,
insideElementRelease: insideElementRelease,
originalEvent: event
});
if ( insideElementPress && this.viewport && stop !== false ) {
this.viewport.applyConstraints();
}
}
function onCanvasScroll( tracker, position, scroll, shift, event ) {
var factor;
if ( this.viewport ) {
var factor,
stop = this.raiseEvent( 'scroll', {
tracker: tracker,
position: position,
scroll: scroll,
shift: shift,
originalEvent: event
});
if ( this.viewport && stop !== false ) {
factor = Math.pow( this.zoomPerScroll, scroll );
this.viewport.zoomBy(
factor,
this.viewport.pointFromPixel( position, true )
);
this.viewport.applyConstraints();
//cancels event
event.stopPropagation();
event.preventDefault();
return false;
}
this.raiseEvent( 'scroll', {
tracker: tracker,
position: position,
scroll: scroll,
shift: shift,
originalEvent: event
});
//cancels event
return false;
}
function onContainerExit( tracker, position, buttonDownElement, buttonDownAny, event ) {
if ( !buttonDownElement ) {
THIS[ this.hash ].mouseInside = false;
if ( !THIS[ this.hash ].animating ) {
beginControlsAutoHide( this );
}
}
this.raiseEvent( 'exit', {
var stop = this.raiseEvent( 'exit', {
tracker: tracker,
position: position,
buttonDownElement: buttonDownElement,
buttonDownAny: buttonDownAny,
originalEvent: event
});
}
function onContainerRelease( tracker, position, insideElementPress, insideElementRelease, event ) {
if ( !insideElementRelease ) {
if ( !buttonDownElement ) {
THIS[ this.hash ].mouseInside = false;
if ( !THIS[ this.hash ].animating ) {
if ( !THIS[ this.hash ].animating && stop !== false ) {
beginControlsAutoHide( this );
}
}
this.raiseEvent( 'release', {
}
function onContainerRelease( tracker, position, insideElementPress, insideElementRelease, event ) {
var stop = this.raiseEvent( 'release', {
tracker: tracker,
position: position,
insideElementPress: insideElementPress,
insideElementRelease: insideElementRelease,
originalEvent: event
});
if ( !insideElementRelease ) {
THIS[ this.hash ].mouseInside = false;
if ( !THIS[ this.hash ].animating && stop !== false ) {
beginControlsAutoHide( this );
}
}
}
function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny, event ) {
var stop;
THIS[ this.hash ].mouseInside = true;
abortControlsAutoHide( this );
this.raiseEvent( 'enter', {
stop = this.raiseEvent( 'enter', {
tracker: tracker,
position: position,
buttonDownElement: buttonDownElement,
buttonDownAny: buttonDownAny,
originalEvent: event
});
if( stop !== false ){
abortControlsAutoHide( this );
}
}
@ -1337,16 +1364,20 @@ function updateOnce( viewer ) {
}
if ( !THIS[ viewer.hash ].animating && animated ) {
viewer.raiseEvent( "animationstart" );
if( false === viewer.raiseEvent( "animationstart" ) ){
return;
}
abortControlsAutoHide( viewer );
}
if ( animated ) {
if( false === viewer.raiseEvent( "animation" ) ){
return;
}
viewer.drawer.update();
if( viewer.navigator ){
viewer.navigator.update( viewer.viewport );
}
viewer.raiseEvent( "animation" );
} else if ( THIS[ viewer.hash ].forceRedraw || viewer.drawer.needsUpdate() ) {
viewer.drawer.update();
if( viewer.navigator ){
@ -1356,7 +1387,9 @@ function updateOnce( viewer ) {
}
if ( THIS[ viewer.hash ].animating && !animated ) {
viewer.raiseEvent( "animationfinish" );
if( false === viewer.raiseEvent( "animationfinish" ) ){
return;
}
if ( !THIS[ viewer.hash ].mouseInside ) {
beginControlsAutoHide( viewer );

View File

@ -77,6 +77,13 @@ $.Viewport.prototype = {
* @return {OpenSeadragon.Viewport} Chainable.
*/
resetContentSize: function( contentSize ){
if( this.viewer ){
if( false === this.viewer.raiseEvent( 'reset', { contentSize: contentSize } ) ){
//cancel event
return this;
}
}
this.contentSize = contentSize;
this.contentAspectX = this.contentSize.x / this.contentSize.y;
this.contentAspectY = this.contentSize.y / this.contentSize.x;
@ -85,13 +92,6 @@ $.Viewport.prototype = {
this.homeBounds = new $.Rect( 0, 0, 1, this.contentAspectY );
if( this.viewer ){
this.viewer.raiseEvent( 'reset-size', {
contentSize: contentSize,
viewer: this.viewer
});
}
return this;
},
@ -133,10 +133,10 @@ $.Viewport.prototype = {
*/
goHome: function( immediately ) {
if( this.viewer ){
this.viewer.raiseEvent( 'home', {
immediately: immediately,
viewer: this.viewer
});
if( false === this.viewer.raiseEvent( 'home', { immediately: immediately } ) ){
//cancel event
return this;
}
}
return this.fitBounds( this.getHomeBounds(), immediately );
},
@ -280,6 +280,13 @@ $.Viewport.prototype = {
dy = 0,
dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
if( this.viewer ){
if( false === this.viewer.raiseEvent( 'constrain', { immediately: immediately } ) ){
//cancel event
return this;
}
}
if ( actualZoom != constrainedZoom ) {
this.zoomTo( constrainedZoom, this.zoomPoint, immediately );
}
@ -332,13 +339,6 @@ $.Viewport.prototype = {
this.fitBounds( bounds, immediately );
}
if( this.viewer ){
this.viewer.raiseEvent( 'constrain', {
immediately: immediately,
viewer: this.viewer
});
}
return this;
},
@ -475,6 +475,18 @@ $.Viewport.prototype = {
* @return {OpenSeadragon.Viewport} Chainable.
*/
panTo: function( center, immediately ) {
var stop;
if( this.viewer ){
stop = this.viewer.raiseEvent( 'pan', {
center: center,
immediately: immediately
});
if( stop === false ){
//cancel event
return this;
}
}
if ( immediately ) {
this.centerSpringX.resetTo( center.x );
this.centerSpringY.resetTo( center.y );
@ -483,13 +495,6 @@ $.Viewport.prototype = {
this.centerSpringY.springTo( center.y );
}
if( this.viewer ){
this.viewer.raiseEvent( 'pan', {
center: center,
immediately: immediately,
viewer: this.viewer
});
}
return this;
},
@ -507,6 +512,18 @@ $.Viewport.prototype = {
* @return {OpenSeadragon.Viewport} Chainable.
*/
zoomTo: function( zoom, refPoint, immediately ) {
var stop;
if( this.viewer ){
stop = this.viewer.raiseEvent( 'zoom', {
zoom: zoom,
refPoint: refPoint,
immediately: immediately
});
if( stop === false ){
//cancel event;
return this;
}
}
this.zoomPoint = refPoint instanceof $.Point ?
refPoint :
@ -518,14 +535,6 @@ $.Viewport.prototype = {
this.zoomSpring.springTo( zoom );
}
if( this.viewer ){
this.viewer.raiseEvent( 'zoom', {
zoom: zoom,
refPoint: refPoint,
immediately: immediately,
viewer: this.viewer
});
}
return this;
},
@ -537,7 +546,19 @@ $.Viewport.prototype = {
resize: function( newContainerSize, maintain ) {
var oldBounds = this.getBounds(),
newBounds = oldBounds,
widthDeltaFactor = newContainerSize.x / this.containerSize.x;
widthDeltaFactor = newContainerSize.x / this.containerSize.x,
stop;
if( this.viewer ){
stop = this.viewer.raiseEvent( 'resize', {
newContainerSize: newContainerSize,
maintain: maintain
});
if( stop === false ){
//cancel event
return this;
}
}
this.containerSize = new $.Point(
newContainerSize.x,
@ -549,14 +570,6 @@ $.Viewport.prototype = {
newBounds.height = newBounds.width / this.getAspectRatio();
}
if( this.viewer ){
this.viewer.raiseEvent( 'resize', {
newContainerSize: newContainerSize,
maintain: maintain,
viewer: this.viewer
});
}
return this.fitBounds( newBounds, true );
},