refactored EventHandlerList to just EventHandler and am prefering a mix-in on the prototype to avoid excess indirection via psuedo-private properties.

This commit is contained in:
thatcher 2011-12-14 18:22:02 -05:00
parent 01153bcb91
commit 7d4ffaa769
6 changed files with 69 additions and 197 deletions

View File

@ -20,7 +20,7 @@
<filelist id="openseadragon.javascript" <filelist id="openseadragon.javascript"
dir="."> dir=".">
<file name="src/openseadragon.js" /> <file name="src/openseadragon.js" />
<file name="src/eventhandlerlist.js" /> <file name="src/eventhandler.js" />
<file name="src/utils.js" /> <file name="src/utils.js" />
<file name="src/mousetracker.js" /> <file name="src/mousetracker.js" />
<file name="src/navcontrol.js" /> <file name="src/navcontrol.js" />

View File

@ -204,16 +204,16 @@ OpenSeadragon = window.OpenSeadragon || (function(){
(function($){ (function($){
$.EventHandlerList = function() { $.EventHandler = function() {
this._list = {}; this.events = {};
}; };
$.EventHandlerList.prototype = { $.EventHandler.prototype = {
addHandler: function(id, handler) { addHandler: function(id, handler) {
var events = this._list[ id ]; var events = this.events[ id ];
if( !events ){ if( !events ){
this._list[ id ] = events = []; this.events[ id ] = events = [];
} }
events[events.length] = handler; events[events.length] = handler;
}, },
@ -222,12 +222,13 @@ OpenSeadragon = window.OpenSeadragon || (function(){
//Start Thatcher - unneccessary indirection. Also, because events were //Start Thatcher - unneccessary indirection. Also, because events were
// - not actually being removed, we need to add the code // - not actually being removed, we need to add the code
// - to do the removal ourselves. TODO // - to do the removal ourselves. TODO
var evt = this._list[ id ]; var evt = this.events[ id ];
if (!evt) return; if (!evt) return;
//End Thatcher //End Thatcher
}, },
getHandler: function(id) { getHandler: function(id) {
var evt = this._list[ id ]; var evt = this.events[ id ];
if (!evt || !evt.length) return null; if (!evt || !evt.length) return null;
evt = evt.length === 1 ? evt = evt.length === 1 ?
[evt[0]] : [evt[0]] :
@ -1270,14 +1271,7 @@ $.NavControl.prototype = {
this.elmt = this._group.element; this.elmt = this._group.element;
this.elmt[$.SIGNAL] = true; // hack to get our controls to fade this.elmt[$.SIGNAL] = true; // hack to get our controls to fade
this._viewer.add_open($.delegate(this, this._lightUp)); this._viewer.addHandler('open', $.delegate(this, this._lightUp));
},
get_events: function() {
return this._events;
},
set_events: function(value) {
this._events = value;
}, },
_resolveUrl: function(url) { _resolveUrl: function(url) {
var prefix = this._viewer.prefixUrl; var prefix = this._viewer.prefixUrl;
@ -1432,6 +1426,8 @@ $.Viewer = function( options ) {
_this = this, _this = this,
i; i;
$.EventHandler.call( this );
if( typeof( options ) != 'object' ){ if( typeof( options ) != 'object' ){
options = { options = {
id: args[ 0 ], id: args[ 0 ],
@ -1527,7 +1523,6 @@ $.Viewer = function( options ) {
this.element = document.getElementById( options.id ); this.element = document.getElementById( options.id );
this.container = $.Utils.makeNeutralElement("div"); this.container = $.Utils.makeNeutralElement("div");
this.canvas = $.Utils.makeNeutralElement("div"); this.canvas = $.Utils.makeNeutralElement("div");
this.events = new $.EventHandlerList();
this._fsBoundsDelta = new $.Point(1, 1); this._fsBoundsDelta = new $.Point(1, 1);
this._prevContainerSize = null; this._prevContainerSize = null;
@ -1629,7 +1624,7 @@ $.Viewer = function( options ) {
} }
}; };
$.Viewer.prototype = { $.extend($.Viewer.prototype, $.EventHandler.prototype, {
_updateMulti: function () { _updateMulti: function () {
if (!this.source) { if (!this.source) {
@ -1641,6 +1636,7 @@ $.Viewer.prototype = {
this._updateOnce(); this._updateOnce();
scheduleUpdate( this, arguments.callee, beginTime ); scheduleUpdate( this, arguments.callee, beginTime );
}, },
_updateOnce: function () { _updateOnce: function () {
if ( !this.source ) { if ( !this.source ) {
return; return;
@ -1686,48 +1682,6 @@ $.Viewer.prototype = {
this.profiler.endUpdate(); this.profiler.endUpdate();
}, },
add_open: function (handler) {
this.events.addHandler("open", handler);
},
remove_open: function (handler) {
this.events.removeHandler("open", handler);
},
add_error: function (handler) {
this.events.addHandler("error", handler);
},
remove_error: function (handler) {
this.events.removeHandler("error", handler);
},
add_ignore: function (handler) {
this.events.addHandler("ignore", handler);
},
remove_ignore: function (handler) {
this.events.removeHandler("ignore", handler);
},
add_resize: function (handler) {
this.events.addHandler("resize", handler);
},
remove_resize: function (handler) {
this.events.removeHandler("resize", handler);
},
add_animationstart: function (handler) {
this.events.addHandler("animationstart", handler);
},
remove_animationstart: function (handler) {
this.events.removeHandler("animationstart", handler);
},
add_animation: function (handler) {
this.events.addHandler("animation", handler);
},
remove_animation: function (handler) {
this.events.removeHandler("animation", handler);
},
add_animationfinish: function (handler) {
this.events.addHandler("animationfinish", handler);
},
remove_animationfinish: function (handler) {
this.events.removeHandler("animationfinish", handler);
},
addControl: function ( elmt, anchor ) { addControl: function ( elmt, anchor ) {
var elmt = $.Utils.getElement( elmt ), var elmt = $.Utils.getElement( elmt ),
div = null; div = null;
@ -2002,7 +1956,7 @@ $.Viewer.prototype = {
this.container.style.visibility = visible ? "" : "hidden"; this.container.style.visibility = visible ? "" : "hidden";
} }
}; });
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Schedulers provide the general engine for animation // Schedulers provide the general engine for animation
@ -2088,9 +2042,10 @@ function abortControlsAutoHide( viewer ) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Event engine is simple, look up event handler and call. // Event engine is simple, look up event handler and call.
// TODO: add the to EventHandler and call it trigger to align with jQuery
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
function raiseEvent( viewer, eventName, eventArgs) { function raiseEvent( viewer, eventName, eventArgs) {
var handler = viewer.events.getHandler( eventName ); var handler = viewer.getHandler( eventName );
if ( handler ) { if ( handler ) {
if (!eventArgs) { if (!eventArgs) {
eventArgs = new Object(); eventArgs = new Object();
@ -2807,6 +2762,8 @@ $.ButtonState = {
$.Button = function( options ) { $.Button = function( options ) {
$.EventHandler.call( this );
this._tooltip = options.tooltip; this._tooltip = options.tooltip;
this._srcRest = options.srcRest; this._srcRest = options.srcRest;
this._srcGroup = options.srcGroup; this._srcGroup = options.srcGroup;
@ -2815,18 +2772,21 @@ $.Button = function( options ) {
this._button = options.button; this._button = options.button;
this.config = options.config; this.config = options.config;
this._events = new $.EventHandlerList(); if ( options.onPress != undefined ){
this.addHandler("onPress", options.onPress );
if ( options.onPress != undefined ) }
this._events.addHandler("onPress", options.onPress ); if ( options.onRelease != undefined ){
if ( options.onRelease != undefined ) this.addHandler("onRelease", options.onRelease );
this._events.addHandler("onRelease", options.onRelease ); }
if ( options.onClick != undefined ) if ( options.onClick != undefined ){
this._events.addHandler("onClick", options.onClick ); this.addHandler("onClick", options.onClick );
if ( options.onEnter != undefined ) }
this._events.addHandler("onEnter", options.onEnter ); if ( options.onEnter != undefined ){
if ( options.onExit != undefined ) this.addHandler("onEnter", options.onEnter );
this._events.addHandler("onExit", options.onExit ); }
if ( options.onExit != undefined ){
this.addHandler("onExit", options.onExit );
}
this._button = $.Utils.makeNeutralElement("span"); this._button = $.Utils.makeNeutralElement("span");
this._currentState = $.ButtonState.GROUP; this._currentState = $.ButtonState.GROUP;
@ -2864,8 +2824,8 @@ $.Button = function( options ) {
styleGroup.left = styleHover.left = styleDown.left = "0px"; styleGroup.left = styleHover.left = styleDown.left = "0px";
styleHover.visibility = styleDown.visibility = "hidden"; styleHover.visibility = styleDown.visibility = "hidden";
if ($.Utils.getBrowser() == $.Browser.FIREFOX && if ( $.Utils.getBrowser() == $.Browser.FIREFOX
$.Utils.getBrowserVersion() < 3) { && $.Utils.getBrowserVersion() < 3 ){
styleGroup.top = styleHover.top = styleDown.top = ""; styleGroup.top = styleHover.top = styleDown.top = "";
} }
@ -2879,7 +2839,7 @@ $.Button = function( options ) {
this._outTo( $.ButtonState.REST ); this._outTo( $.ButtonState.REST );
}; };
$.Button.prototype = { $.extend( $.Button.prototype, $.EventHandler.prototype, {
_scheduleFade: function() { _scheduleFade: function() {
window.setTimeout($.delegate(this, this._updateFade), 20); window.setTimeout($.delegate(this, this._updateFade), 20);
}, },
@ -2972,11 +2932,8 @@ $.Button.prototype = {
this._raiseEvent("onClick", this); this._raiseEvent("onClick", this);
} }
}, },
get_events: function get_events() {
return this._events;
},
_raiseEvent: function(eventName, eventArgs) { _raiseEvent: function(eventName, eventArgs) {
var handler = this.get_events().getHandler(eventName); var handler = this.getHandler(eventName);
if (handler) { if (handler) {
if (!eventArgs) { if (!eventArgs) {
@ -3031,7 +2988,7 @@ $.Button.prototype = {
notifyGroupExit: function() { notifyGroupExit: function() {
this._outTo($.ButtonState.REST); this._outTo($.ButtonState.REST);
} }
}; });
}( OpenSeadragon )); }( OpenSeadragon ));

View File

@ -10,6 +10,8 @@ $.ButtonState = {
$.Button = function( options ) { $.Button = function( options ) {
$.EventHandler.call( this );
this._tooltip = options.tooltip; this._tooltip = options.tooltip;
this._srcRest = options.srcRest; this._srcRest = options.srcRest;
this._srcGroup = options.srcGroup; this._srcGroup = options.srcGroup;
@ -18,18 +20,21 @@ $.Button = function( options ) {
this._button = options.button; this._button = options.button;
this.config = options.config; this.config = options.config;
this._events = new $.EventHandlerList(); if ( options.onPress != undefined ){
this.addHandler("onPress", options.onPress );
if ( options.onPress != undefined ) }
this._events.addHandler("onPress", options.onPress ); if ( options.onRelease != undefined ){
if ( options.onRelease != undefined ) this.addHandler("onRelease", options.onRelease );
this._events.addHandler("onRelease", options.onRelease ); }
if ( options.onClick != undefined ) if ( options.onClick != undefined ){
this._events.addHandler("onClick", options.onClick ); this.addHandler("onClick", options.onClick );
if ( options.onEnter != undefined ) }
this._events.addHandler("onEnter", options.onEnter ); if ( options.onEnter != undefined ){
if ( options.onExit != undefined ) this.addHandler("onEnter", options.onEnter );
this._events.addHandler("onExit", options.onExit ); }
if ( options.onExit != undefined ){
this.addHandler("onExit", options.onExit );
}
this._button = $.Utils.makeNeutralElement("span"); this._button = $.Utils.makeNeutralElement("span");
this._currentState = $.ButtonState.GROUP; this._currentState = $.ButtonState.GROUP;
@ -67,8 +72,8 @@ $.Button = function( options ) {
styleGroup.left = styleHover.left = styleDown.left = "0px"; styleGroup.left = styleHover.left = styleDown.left = "0px";
styleHover.visibility = styleDown.visibility = "hidden"; styleHover.visibility = styleDown.visibility = "hidden";
if ($.Utils.getBrowser() == $.Browser.FIREFOX && if ( $.Utils.getBrowser() == $.Browser.FIREFOX
$.Utils.getBrowserVersion() < 3) { && $.Utils.getBrowserVersion() < 3 ){
styleGroup.top = styleHover.top = styleDown.top = ""; styleGroup.top = styleHover.top = styleDown.top = "";
} }
@ -82,7 +87,7 @@ $.Button = function( options ) {
this._outTo( $.ButtonState.REST ); this._outTo( $.ButtonState.REST );
}; };
$.Button.prototype = { $.extend( $.Button.prototype, $.EventHandler.prototype, {
_scheduleFade: function() { _scheduleFade: function() {
window.setTimeout($.delegate(this, this._updateFade), 20); window.setTimeout($.delegate(this, this._updateFade), 20);
}, },
@ -175,11 +180,8 @@ $.Button.prototype = {
this._raiseEvent("onClick", this); this._raiseEvent("onClick", this);
} }
}, },
get_events: function get_events() {
return this._events;
},
_raiseEvent: function(eventName, eventArgs) { _raiseEvent: function(eventName, eventArgs) {
var handler = this.get_events().getHandler(eventName); var handler = this.getHandler(eventName);
if (handler) { if (handler) {
if (!eventArgs) { if (!eventArgs) {
@ -234,6 +236,6 @@ $.Button.prototype = {
notifyGroupExit: function() { notifyGroupExit: function() {
this._outTo($.ButtonState.REST); this._outTo($.ButtonState.REST);
} }
}; });
}( OpenSeadragon )); }( OpenSeadragon ));

View File

@ -1,41 +0,0 @@
(function($){
$.EventHandlerList = function() {
this._list = {};
};
$.EventHandlerList.prototype = {
addHandler: function(id, handler) {
var events = this._list[ id ];
if( !events ){
this._list[ id ] = events = [];
}
events[events.length] = handler;
},
removeHandler: function(id, handler) {
//Start Thatcher - unneccessary indirection. Also, because events were
// - not actually being removed, we need to add the code
// - to do the removal ourselves. TODO
var evt = this._list[ id ];
if (!evt) return;
//End Thatcher
},
getHandler: function(id) {
var evt = this._list[ id ];
if (!evt || !evt.length) return null;
evt = evt.length === 1 ?
[evt[0]] :
Array.apply( null, evt );
return function(source, args) {
for (var i = 0, l = evt.length; i < l; i++) {
evt[i](source, args);
}
};
}
};
}( OpenSeadragon ));

View File

@ -76,14 +76,7 @@ $.NavControl.prototype = {
this.elmt = this._group.element; this.elmt = this._group.element;
this.elmt[$.SIGNAL] = true; // hack to get our controls to fade this.elmt[$.SIGNAL] = true; // hack to get our controls to fade
this._viewer.add_open($.delegate(this, this._lightUp)); this._viewer.addHandler('open', $.delegate(this, this._lightUp));
},
get_events: function() {
return this._events;
},
set_events: function(value) {
this._events = value;
}, },
_resolveUrl: function(url) { _resolveUrl: function(url) {
var prefix = this._viewer.prefixUrl; var prefix = this._viewer.prefixUrl;

View File

@ -28,6 +28,8 @@ $.Viewer = function( options ) {
_this = this, _this = this,
i; i;
$.EventHandler.call( this );
if( typeof( options ) != 'object' ){ if( typeof( options ) != 'object' ){
options = { options = {
id: args[ 0 ], id: args[ 0 ],
@ -123,7 +125,6 @@ $.Viewer = function( options ) {
this.element = document.getElementById( options.id ); this.element = document.getElementById( options.id );
this.container = $.Utils.makeNeutralElement("div"); this.container = $.Utils.makeNeutralElement("div");
this.canvas = $.Utils.makeNeutralElement("div"); this.canvas = $.Utils.makeNeutralElement("div");
this.events = new $.EventHandlerList();
this._fsBoundsDelta = new $.Point(1, 1); this._fsBoundsDelta = new $.Point(1, 1);
this._prevContainerSize = null; this._prevContainerSize = null;
@ -225,7 +226,7 @@ $.Viewer = function( options ) {
} }
}; };
$.Viewer.prototype = { $.extend($.Viewer.prototype, $.EventHandler.prototype, {
_updateMulti: function () { _updateMulti: function () {
if (!this.source) { if (!this.source) {
@ -237,6 +238,7 @@ $.Viewer.prototype = {
this._updateOnce(); this._updateOnce();
scheduleUpdate( this, arguments.callee, beginTime ); scheduleUpdate( this, arguments.callee, beginTime );
}, },
_updateOnce: function () { _updateOnce: function () {
if ( !this.source ) { if ( !this.source ) {
return; return;
@ -282,48 +284,6 @@ $.Viewer.prototype = {
this.profiler.endUpdate(); this.profiler.endUpdate();
}, },
add_open: function (handler) {
this.events.addHandler("open", handler);
},
remove_open: function (handler) {
this.events.removeHandler("open", handler);
},
add_error: function (handler) {
this.events.addHandler("error", handler);
},
remove_error: function (handler) {
this.events.removeHandler("error", handler);
},
add_ignore: function (handler) {
this.events.addHandler("ignore", handler);
},
remove_ignore: function (handler) {
this.events.removeHandler("ignore", handler);
},
add_resize: function (handler) {
this.events.addHandler("resize", handler);
},
remove_resize: function (handler) {
this.events.removeHandler("resize", handler);
},
add_animationstart: function (handler) {
this.events.addHandler("animationstart", handler);
},
remove_animationstart: function (handler) {
this.events.removeHandler("animationstart", handler);
},
add_animation: function (handler) {
this.events.addHandler("animation", handler);
},
remove_animation: function (handler) {
this.events.removeHandler("animation", handler);
},
add_animationfinish: function (handler) {
this.events.addHandler("animationfinish", handler);
},
remove_animationfinish: function (handler) {
this.events.removeHandler("animationfinish", handler);
},
addControl: function ( elmt, anchor ) { addControl: function ( elmt, anchor ) {
var elmt = $.Utils.getElement( elmt ), var elmt = $.Utils.getElement( elmt ),
div = null; div = null;
@ -598,7 +558,7 @@ $.Viewer.prototype = {
this.container.style.visibility = visible ? "" : "hidden"; this.container.style.visibility = visible ? "" : "hidden";
} }
}; });
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Schedulers provide the general engine for animation // Schedulers provide the general engine for animation
@ -684,9 +644,10 @@ function abortControlsAutoHide( viewer ) {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Event engine is simple, look up event handler and call. // Event engine is simple, look up event handler and call.
// TODO: add the to EventHandler and call it trigger to align with jQuery
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
function raiseEvent( viewer, eventName, eventArgs) { function raiseEvent( viewer, eventName, eventArgs) {
var handler = viewer.events.getHandler( eventName ); var handler = viewer.getHandler( eventName );
if ( handler ) { if ( handler ) {
if (!eventArgs) { if (!eventArgs) {
eventArgs = new Object(); eventArgs = new Object();