finally managed to clean up MouseTracker, actually uses the prototype pattern. probably too many public methods but that can be cleaned up later.

This commit is contained in:
thatcher 2012-02-01 16:56:04 -05:00
parent 5cba11c91c
commit ec77bb2a78
6 changed files with 930 additions and 738 deletions

View File

@ -512,7 +512,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
*/ */
getPageScroll: function() { getPageScroll: function() {
var result = new $.Point(), var result = new $.Point(),
docElmt = document.documentElement || {}, docElement = document.documentElement || {},
body = document.body || {}; body = document.body || {};
if ( typeof( window.pageXOffset ) == "number" ) { if ( typeof( window.pageXOffset ) == "number" ) {
@ -521,9 +521,9 @@ OpenSeadragon = window.OpenSeadragon || (function(){
} else if ( body.scrollLeft || body.scrollTop ) { } else if ( body.scrollLeft || body.scrollTop ) {
result.x = body.scrollLeft; result.x = body.scrollLeft;
result.y = body.scrollTop; result.y = body.scrollTop;
} else if ( docElmt.scrollLeft || docElmt.scrollTop ) { } else if ( docElement.scrollLeft || docElement.scrollTop ) {
result.x = docElmt.scrollLeft; result.x = docElement.scrollLeft;
result.y = docElmt.scrollTop; result.y = docElement.scrollTop;
} }
return result; return result;
@ -537,15 +537,15 @@ OpenSeadragon = window.OpenSeadragon || (function(){
*/ */
getWindowSize: function() { getWindowSize: function() {
var result = new $.Point(), var result = new $.Point(),
docElmt = document.documentElement || {}, docElement = document.documentElement || {},
body = document.body || {}; body = document.body || {};
if ( typeof( window.innerWidth ) == 'number' ) { if ( typeof( window.innerWidth ) == 'number' ) {
result.x = window.innerWidth; result.x = window.innerWidth;
result.y = window.innerHeight; result.y = window.innerHeight;
} else if ( docElmt.clientWidth || docElmt.clientHeight ) { } else if ( docElement.clientWidth || docElement.clientHeight ) {
result.x = docElmt.clientWidth; result.x = docElement.clientWidth;
result.y = docElmt.clientHeight; result.y = docElement.clientHeight;
} else if ( body.clientWidth || body.clientHeight ) { } else if ( body.clientWidth || body.clientHeight ) {
result.x = body.clientWidth; result.x = body.clientWidth;
result.y = body.clientHeight; result.y = body.clientHeight;
@ -1278,8 +1278,7 @@ $.EventHandler.prototype = {
return; return;
} }
var isIE = $.Browser.vendor == $.BROWSERS.IE, var buttonDownAny = false,
buttonDownAny = false,
ieCapturingAny = false, ieCapturingAny = false,
ieTrackersActive = {}, // dictionary from hash to MouseTracker ieTrackersActive = {}, // dictionary from hash to MouseTracker
ieTrackersCapturing = []; // list of trackers interested in capture ieTrackersCapturing = []; // list of trackers interested in capture
@ -1287,252 +1286,335 @@ $.EventHandler.prototype = {
/** /**
* @class * @class
*/ */
$.MouseTracker = function (elmt, clickTimeThreshold, clickDistThreshold) { $.MouseTracker = function ( element, clickTimeThreshold, clickDistThreshold ) {
//Start Thatcher - TODO: remove local function definitions in favor of //Start Thatcher - TODO: remove local function definitions in favor of
// - a global closure for MouseTracker so the number // - a global closure for MouseTracker so the number
// - of Viewers has less memory impact. Also use // - of Viewers has less memory impact. Also use
// - prototype pattern instead of Singleton pattern. // - prototype pattern instead of Singleton pattern.
//End Thatcher //End Thatcher
var self = this,
ieSelf = null,
hash = Math.random(), // a unique hash for this tracker this.hash = Math.random(); // a unique hash for this tracker
elmt = $.getElement(elmt), this.element = $.getElement( element );
tracking = false, this.tracking = false;
capturing = false, this.capturing = false;
buttonDownElmt = false, this.buttonDownElement = false;
insideElmt = false, this.insideElement = false;
lastPoint = null, // position of last mouse down/move this.lastPoint = null; // position of last mouse down/move
lastMouseDownTime = null, // time of last mouse down this.lastMouseDownTime = null; // time of last mouse down
lastMouseDownPoint = null, // position of last mouse down this.lastMouseDownPoint = null; // position of last mouse down
clickTimeThreshold = clickTimeThreshold, this.clickTimeThreshold = clickTimeThreshold;
clickDistThreshold = clickDistThreshold; this.clickDistThreshold = clickDistThreshold;
this.target = elmt; this.target = element;
this.enterHandler = null; // function(tracker, position, buttonDownElmt, buttonDownAny) this.enterHandler = null; // function(tracker, position, buttonDownElement, buttonDownAny)
this.exitHandler = null; // function(tracker, position, buttonDownElmt, buttonDownAny) this.exitHandler = null; // function(tracker, position, buttonDownElement, buttonDownAny)
this.pressHandler = null; // function(tracker, position) this.pressHandler = null; // function(tracker, position)
this.releaseHandler = null; // function(tracker, position, insideElmtPress, insideElmtRelease) this.releaseHandler = null; // function(tracker, position, insideElementPress, insideElementRelease)
this.scrollHandler = null; // function(tracker, position, scroll, shift) this.scrollHandler = null; // function(tracker, position, scroll, shift)
this.clickHandler = null; // function(tracker, position, quick, shift) this.clickHandler = null; // function(tracker, position, quick, shift)
this.dragHandler = null; // function(tracker, position, delta, shift) this.dragHandler = null; // function(tracker, position, delta, shift)
(function () { this.delegates = {
ieSelf = { "mouseover": $.delegate(this, this.onMouseOver),
hasMouse: hasMouse, "mouseout": $.delegate(this, this.onMouseOut),
onMouseOver: onMouseOver, "mousedown": $.delegate(this, this.onMouseDown),
onMouseOut: onMouseOut, "mouseup": $.delegate(this, this.onMouseUp),
onMouseUp: onMouseUp, "click": $.delegate(this, this.onMouseClick),
onMouseMove: onMouseMove "DOMMouseScroll": $.delegate(this, this.onMouseWheelSpin),
}; "mousewheel": $.delegate(this, this.onMouseWheelSpin),
})(); "mouseupie": $.delegate(this, this.onMouseUpIE),
"mousemoveie": $.delegate(this, this.onMouseMoveIE),
"mouseupwindow": $.delegate(this, this.onMouseUpWindow),
this.isTracking = function () { "mousemove": $.delegate(this, this.onMouseMove)
return tracking;
}; };
this.setTracking = function (track) { };
$.MouseTracker.prototype = {
/**
* @method
*/
isTracking: function () {
return this.tracking;
},
/**
* @method
*/
setTracking: function ( track ) {
if ( track ) { if ( track ) {
startTracking(); this.startTracking();
} else { } else {
stopTracking(); this.stopTracking();
} }
}; },
function startTracking() { /**
if (!tracking) { * @method
$.addEvent(elmt, "mouseover", onMouseOver, false); */
$.addEvent(elmt, "mouseout", onMouseOut, false); startTracking: function() {
$.addEvent(elmt, "mousedown", onMouseDown, false); if ( !this.tracking ) {
$.addEvent(elmt, "mouseup", onMouseUp, false); $.addEvent( this.element, "mouseover", this.delegates["mouseover"], false);
$.addEvent(elmt, "click", onMouseClick, false); $.addEvent( this.element, "mouseout", this.delegates["mouseout"], false);
$.addEvent(elmt, "DOMMouseScroll", onMouseWheelSpin, false); $.addEvent( this.element, "mousedown", this.delegates["mousedown"], false);
$.addEvent(elmt, "mousewheel", onMouseWheelSpin, false); // Firefox $.addEvent( this.element, "mouseup", this.delegates["mouseup"], false);
$.addEvent( this.element, "click", this.delegates["click"], false);
$.addEvent( this.element, "DOMMouseScroll", this.delegates["DOMMouseScroll"], false);
$.addEvent( this.element, "mousewheel", this.delegates["mousewheel"], false); // Firefox
tracking = true; this.tracking = true;
ieTrackersActive[hash] = ieSelf; ieTrackersActive[ this.hash ] = this;
}
} }
},
function stopTracking() { /**
if (tracking) { * @method
$.removeEvent(elmt, "mouseover", onMouseOver, false); */
$.removeEvent(elmt, "mouseout", onMouseOut, false); stopTracking: function() {
$.removeEvent(elmt, "mousedown", onMouseDown, false); if ( this.tracking ) {
$.removeEvent(elmt, "mouseup", onMouseUp, false); $.removeEvent( this.element, "mouseover", this.delegates["mouseover"], false);
$.removeEvent(elmt, "click", onMouseClick, false); $.removeEvent( this.element, "mouseout", this.delegates["mouseout"], false);
$.removeEvent(elmt, "DOMMouseScroll", onMouseWheelSpin, false); $.removeEvent( this.element, "mousedown", this.delegates["mousedown"], false);
$.removeEvent(elmt, "mousewheel", onMouseWheelSpin, false); $.removeEvent( this.element, "mouseup", this.delegates["mouseup"], false);
$.removeEvent( this.element, "click", this.delegates["click"], false);
$.removeEvent( this.element, "DOMMouseScroll", this.delegates["DOMMouseScroll"], false);
$.removeEvent( this.element, "mousewheel", this.delegates["mousewheel"], false);
releaseMouse(); this.releaseMouse();
tracking = false; this.tracking = false;
delete ieTrackersActive[hash]; delete ieTrackersActive[ this.hash ];
}
} }
},
function captureMouse() { /**
if (!capturing) { * @method
if (isIE) { */
$.removeEvent(elmt, "mouseup", onMouseUp, false); captureMouse: function() {
$.addEvent(elmt, "mouseup", onMouseUpIE, true); if ( !this.capturing ) {
$.addEvent(elmt, "mousemove", onMouseMoveIE, true); if ( $.Browser.vendor == $.BROWSERS.IE ) {
$.removeEvent( this.element, "mouseup", this.delegates["mouseup"], false );
$.addEvent( this.element, "mouseup", this.delegates["mouseupie"], true );
$.addEvent( this.element, "mousemove", this.delegates["mousemoveie"], true );
} else { } else {
$.addEvent(window, "mouseup", onMouseUpWindow, true); $.addEvent( window, "mouseup", this.delegates["mouseupwindow"], true );
$.addEvent(window, "mousemove", onMouseMove, true); $.addEvent( window, "mousemove", this.delegates["mousemove"], true );
} }
capturing = true; this.capturing = true;
}
} }
},
function releaseMouse() {
if (capturing) { /**
if (isIE) { * @method
$.removeEvent(elmt, "mousemove", onMouseMoveIE, true); */
$.removeEvent(elmt, "mouseup", onMouseUpIE, true); releaseMouse: function() {
$.addEvent(elmt, "mouseup", onMouseUp, false); if ( this.capturing ) {
if ( $.Browser.vendor == $.BROWSERS.IE ) {
$.removeEvent( this.element, "mousemove", this.delegates["mousemoveie"], true );
$.removeEvent( this.element, "mouseup", this.delegates["mouseupie"], true );
$.addEvent( this.element, "mouseup", this.delegates["mouseup"], false );
} else { } else {
$.removeEvent(window, "mousemove", onMouseMove, true); $.removeEvent( window, "mousemove", this.delegates["mousemove"], true );
$.removeEvent(window, "mouseup", onMouseUpWindow, true); $.removeEvent( window, "mouseup", this.delegates["mouseupwindow"], true );
} }
capturing = false; this.capturing = false;
}
} }
},
function triggerOthers(eventName, event) { /**
var trackers = ieTrackersActive; * @method
for (var otherHash in trackers) { */
if (trackers.hasOwnProperty(otherHash) && hash != otherHash) { triggerOthers: function( eventName, event ) {
var trackers = ieTrackersActive,
otherHash;
for ( otherHash in trackers ) {
if ( trackers.hasOwnProperty( otherHash ) && this.hash != otherHash ) {
trackers[ otherHash ][ eventName ]( event ); trackers[ otherHash ][ eventName ]( event );
} }
} }
} },
function hasMouse() { /**
return insideElmt; * @method
} */
hasMouse: function() {
return this.insideElement;
},
function onMouseOver(event) { /**
* @method
*/
onMouseOver: function( event ) {
var event = $.getEvent( event ); var event = $.getEvent( event );
if (isIE && capturing && !isChild(event.srcElement, elmt)) { if ( $.Browser.vendor == $.BROWSERS.IE &&
triggerOthers("onMouseOver", event); this.capturing &&
!isChild( event.srcElement, this.element ) ) {
this.triggerOthers( "onMouseOver", event );
} }
var to = event.target ? event.target : event.srcElement; var to = event.target ?
var from = event.relatedTarget ? event.relatedTarget : event.fromElement; event.target :
if (!isChild(elmt, to) || isChild(elmt, from)) { event.srcElement,
from = event.relatedTarget ?
event.relatedTarget :
event.fromElement;
if ( !isChild( this.element, to ) || isChild( this.element, from ) ) {
return; return;
} }
insideElmt = true; this.insideElement = true;
if (typeof (self.enterHandler) == "function") { if ( typeof( this.enterHandler ) == "function") {
try { try {
self.enterHandler(self, getMouseRelative(event, elmt), this.enterHandler(
buttonDownElmt, buttonDownAny); this,
getMouseRelative( event, this.element ),
this.buttonDownElement,
buttonDownAny
);
} catch ( e ) { } catch ( e ) {
$.console.error(e.name + $.console.error(
" while executing enter handler: " + e.message, e); e.name + " while executing enter handler: " + e.message,
} e
);
} }
} }
},
function onMouseOut(event) { /**
* @method
*/
onMouseOut: function( event ) {
var event = $.getEvent( event ); var event = $.getEvent( event );
if (isIE && capturing && !isChild(event.srcElement, elmt)) { if ( $.Browser.vendor == $.BROWSERS.IE &&
triggerOthers("onMouseOut", event); this.capturing &&
!isChild( event.srcElement, this.element ) ) {
this.triggerOthers( "onMouseOut", event );
} }
var from = event.target ? event.target : event.srcElement; var from = event.target ?
var to = event.relatedTarget ? event.relatedTarget : event.toElement; event.target :
if (!isChild(elmt, from) || isChild(elmt, to)) { event.srcElement,
to = event.relatedTarget ?
event.relatedTarget :
event.toElement;
if ( !isChild( this.element, from ) || isChild( this.element, to ) ) {
return; return;
} }
insideElmt = false; this.insideElement = false;
if (typeof (self.exitHandler) == "function") { if ( typeof( this.exitHandler ) == "function" ) {
try { try {
self.exitHandler(self, getMouseRelative(event, elmt), this.exitHandler(
buttonDownElmt, buttonDownAny); this,
getMouseRelative( event, this.element ),
this.buttonDownElement,
buttonDownAny
);
} catch ( e ) { } catch ( e ) {
$.console.error(e.name + $.console.error(
" while executing exit handler: " + e.message, e); e.name + " while executing exit handler: " + e.message,
} e
);
} }
} }
},
function onMouseDown(event) { /**
* @method
* @inner
*/
onMouseDown: function( event ) {
var event = $.getEvent( event ); var event = $.getEvent( event );
if ( event.button == 2 ) { if ( event.button == 2 ) {
return; return;
} }
buttonDownElmt = true; this.buttonDownElement = true;
lastPoint = getMouseAbsolute(event); this.lastPoint = getMouseAbsolute( event );
lastMouseDownPoint = lastPoint; this.lastMouseDownPoint = this.lastPoint;
lastMouseDownTime = new Date().getTime(); this.lastMouseDownTime = new Date().getTime();
if (typeof (self.pressHandler) == "function") { if ( typeof( this.pressHandler ) == "function" ) {
try { try {
self.pressHandler(self, getMouseRelative(event, elmt)); this.pressHandler(
this,
getMouseRelative( event, this.element )
);
} catch (e) { } catch (e) {
$.console.error(e.name + $.console.error(
" while executing press handler: " + e.message, e); e.name + " while executing press handler: " + e.message,
e
);
} }
} }
if (self.pressHandler || self.dragHandler) { if ( this.pressHandler || this.dragHandler ) {
$.cancelEvent( event ); $.cancelEvent( event );
} }
if (!isIE || !ieCapturingAny) { if ( !( $.Browser.vendor == $.BROWSERS.IE ) || !ieCapturingAny ) {
captureMouse(); this.captureMouse();
ieCapturingAny = true; ieCapturingAny = true;
ieTrackersCapturing = [ieSelf]; // reset to empty & add us ieTrackersCapturing = [ this ]; // reset to empty & add us
} else if (isIE) { } else if ( $.Browser.vendor == $.BROWSERS.IE ) {
ieTrackersCapturing.push(ieSelf); // add us to the list ieTrackersCapturing.push( this ); // add us to the list
}
} }
},
function onMouseUp(event) { /**
var event = $.getEvent(event); * @method
var insideElmtPress = buttonDownElmt; */
var insideElmtRelease = insideElmt; onMouseUp: function( event ) {
var event = $.getEvent( event ),
insideElementPress = this.buttonDownElement,
insideElementRelease = this.insideElement;
if ( event.button == 2 ) { if ( event.button == 2 ) {
return; return;
} }
buttonDownElmt = false; this.buttonDownElement = false;
if (typeof (self.releaseHandler) == "function") { if ( typeof( this.releaseHandler ) == "function" ) {
try { try {
self.releaseHandler(self, getMouseRelative(event, elmt), this.releaseHandler(
insideElmtPress, insideElmtRelease); this,
getMouseRelative( event, this.element ),
insideElementPress,
insideElementRelease
);
} catch (e) { } catch (e) {
$.console.error(e.name + $.console.error(
" while executing release handler: " + e.message, e); e.name + " while executing release handler: " + e.message,
e
);
} }
} }
if (insideElmtPress && insideElmtRelease) { if ( insideElementPress && insideElementRelease ) {
handleMouseClick(event); this.handleMouseClick( event );
}
} }
},
/** /**
* @method
* Only triggered once by the deepest element that initially received * Only triggered once by the deepest element that initially received
* the mouse down event. We want to make sure THIS event doesn't bubble. * the mouse down event. We want to make sure THIS event doesn't bubble.
* Instead, we want to trigger the elements that initially received the * Instead, we want to trigger the elements that initially received the
@ -1540,164 +1622,178 @@ $.EventHandler.prototype = {
* inside them. Then, we want to release capture, and emulate a regular * inside them. Then, we want to release capture, and emulate a regular
* mouseup on the event that this event was meant for. * mouseup on the event that this event was meant for.
*/ */
function onMouseUpIE(event) { onMouseUpIE: function( event ) {
var event = $.getEvent(event); var event = $.getEvent( event ),
tracker,
i;
if ( event.button == 2 ) { if ( event.button == 2 ) {
return; return;
} }
for (var i = 0; i < ieTrackersCapturing.length; i++) { for ( i = 0; i < ieTrackersCapturing.length; i++ ) {
var tracker = ieTrackersCapturing[i]; tracker = ieTrackersCapturing[ i ];
if ( !tracker.hasMouse() ) { if ( !tracker.hasMouse() ) {
tracker.onMouseUp( event ); tracker.onMouseUp( event );
} }
} }
releaseMouse(); this.releaseMouse();
ieCapturingAny = false; ieCapturingAny = false;
event.srcElement.fireEvent("on" + event.type, event.srcElement.fireEvent(
document.createEventObject(event)); "on" + event.type,
document.createEventObject( event )
);
$.stopEvent( event ); $.stopEvent( event );
} },
/** /**
* @private * @method
* @inner
* Only triggered in W3C browsers by elements within which the mouse was * Only triggered in W3C browsers by elements within which the mouse was
* initially pressed, since they are now listening to the window for * initially pressed, since they are now listening to the window for
* mouseup during the capture phase. We shouldn't handle the mouseup * mouseup during the capture phase. We shouldn't handle the mouseup
* here if the mouse is still inside this element, since the regular * here if the mouse is still inside this element, since the regular
* mouseup handler will still fire. * mouseup handler will still fire.
*/ */
function onMouseUpWindow(event) { onMouseUpWindow: function( event ) {
if (!insideElmt) { if ( !this.insideElement ) {
onMouseUp(event); this.onMouseUp( event );
} }
releaseMouse(); this.releaseMouse();
} },
/** /**
* @private * @method
* @inner
*/ */
function onMouseClick(event) { onMouseClick: function( event ) {
if (self.clickHandler) { if ( this.clickHandler ) {
$.cancelEvent( event ); $.cancelEvent( event );
} }
} },
/** /**
* @private * @method
* @inner
*/ */
function onMouseWheelSpin(event) { onMouseWheelSpin: function( event ) {
var nDelta = 0; var nDelta = 0;
if ( !event ) { // For IE, access the global (window) event object if ( !event ) { // For IE, access the global (window) event object
event = window.event; event = window.event;
} }
if ( event.wheelDelta ) { // IE and Opera if ( event.wheelDelta ) { // IE and Opera
nDelta = event.wheelDelta; nDelta = event.wheelDelta;
if ( window.opera ) { // Opera has the values reversed if ( window.opera ) { // Opera has the values reversed
nDelta = -nDelta; nDelta = -nDelta;
} }
} } else if (event.detail) { // Mozilla FireFox
else if (event.detail) { // Mozilla FireFox
nDelta = -event.detail; nDelta = -event.detail;
} }
nDelta = nDelta > 0 ? 1 : -1; nDelta = nDelta > 0 ? 1 : -1;
if (typeof (self.scrollHandler) == "function") { if ( typeof( this.scrollHandler ) == "function" ) {
try { try {
self.scrollHandler(self, getMouseRelative(event, elmt), nDelta, event.shiftKey); this.scrollHandler(
} catch (e) { this,
$.console.error(e.name + getMouseRelative( event, this.element ),
" while executing scroll handler: " + e.message, e); nDelta,
}
$.cancelEvent(event);
}
}
/**
* @private
* @inner
*/
function handleMouseClick(event) {
var event = $.getEvent(event);
if (event.button == 2) {
return;
}
var time = new Date().getTime() - lastMouseDownTime;
var point = getMouseAbsolute(event);
var distance = lastMouseDownPoint.distanceTo(point);
var quick = time <= clickTimeThreshold &&
distance <= clickDistThreshold;
if (typeof (self.clickHandler) == "function") {
try {
self.clickHandler(self, getMouseRelative(event, elmt),
quick, event.shiftKey);
} catch (e) {
$.console.error(e.name +
" while executing click handler: " + e.message, e);
}
}
}
/**
* @private
* @inner
*/
function onMouseMove(event) {
var event = $.getEvent(event);
var point = getMouseAbsolute(event);
var delta = point.minus(lastPoint);
lastPoint = point;
if (typeof (self.dragHandler) == "function") {
try {
self.dragHandler(
self,
getMouseRelative( event, elmt ),
delta,
event.shiftKey event.shiftKey
); );
} catch (e) { } catch (e) {
$.console.error( $.console.error(
e.name + e.name + " while executing scroll handler: " + e.message,
" while executing drag handler: "
+ e.message,
e e
); );
} }
$.cancelEvent( event ); $.cancelEvent( event );
} }
}; },
/**
* @method
*/
handleMouseClick: function( event ) {
var event = $.getEvent( event );
if ( event.button == 2 ) {
return;
}
var time = new Date().getTime() - this.lastMouseDownTime;
var point = getMouseAbsolute( event );
var distance = this.lastMouseDownPoint.distanceTo( point );
var quick = (
time <= this.clickTimeThreshold
) && (
distance <= this.clickDistThreshold
);
if ( typeof( this.clickHandler ) == "function" ) {
try {
this.clickHandler(
this,
getMouseRelative( event, this.element ),
quick,
event.shiftKey
);
} catch ( e ) {
$.console.error(
e.name + " while executing click handler: " + e.message,
e
);
}
}
},
/**
* @method
*/
onMouseMove: function( event ) {
var event = $.getEvent( event );
var point = getMouseAbsolute( event );
var delta = point.minus( this.lastPoint );
this.lastPoint = point;
if ( typeof( this.dragHandler ) == "function" ) {
try {
this.dragHandler(
this,
getMouseRelative( event, this.element ),
delta,
event.shiftKey
);
} catch (e) {
$.console.error(
e.name + " while executing drag handler: " + e.message,
e
);
}
$.cancelEvent( event );
}
},
/** /**
* @private
* @inner
* Only triggered once by the deepest element that initially received * Only triggered once by the deepest element that initially received
* the mouse down event. Since no other element has captured the mouse, * the mouse down event. Since no other element has captured the mouse,
* we want to trigger the elements that initially received the mouse * we want to trigger the elements that initially received the mouse
* down event (including this one). * down event (including this one).
* @method
*/ */
function onMouseMoveIE(event) { onMouseMoveIE: function( event ) {
for (var i = 0; i < ieTrackersCapturing.length; i++) { var i;
for ( i = 0; i < ieTrackersCapturing.length; i++ ) {
ieTrackersCapturing[ i ].onMouseMove( event ); ieTrackersCapturing[ i ].onMouseMove( event );
} }
$.stopEvent( event ); $.stopEvent( event );
}; }
}; };
@ -1707,35 +1803,35 @@ $.EventHandler.prototype = {
*/ */
function getMouseAbsolute( event ) { function getMouseAbsolute( event ) {
return $.getMousePosition( event ); return $.getMousePosition( event );
} };
/** /**
* @private * @private
* @inner * @inner
*/ */
function getMouseRelative( event, elmt ) { function getMouseRelative( event, element ) {
var mouse = $.getMousePosition(event); var mouse = $.getMousePosition( event ),
var offset = $.getElementPosition(elmt); offset = $.getElementPosition( element );
return mouse.minus( offset ); return mouse.minus( offset );
} };
/** /**
* @private * @private
* @inner * @inner
* Returns true if elmtB is a child node of elmtA, or if they're equal. * Returns true if elementB is a child node of elementA, or if they're equal.
*/ */
function isChild( elmtA, elmtB ) { function isChild( elementA, elementB ) {
var body = document.body; var body = document.body;
while (elmtB && elmtA != elmtB && body != elmtB) { while ( elementB && elementA != elementB && body != elementB ) {
try { try {
elmtB = elmtB.parentNode; elementB = elementB.parentNode;
} catch (e) { } catch (e) {
return false; return false;
} }
} }
return elmtA == elmtB; return elementA == elementB;
} };
/** /**
* @private * @private
@ -1743,7 +1839,7 @@ $.EventHandler.prototype = {
*/ */
function onGlobalMouseDown() { function onGlobalMouseDown() {
buttonDownAny = true; buttonDownAny = true;
} };
/** /**
* @private * @private
@ -1751,11 +1847,11 @@ $.EventHandler.prototype = {
*/ */
function onGlobalMouseUp() { function onGlobalMouseUp() {
buttonDownAny = false; buttonDownAny = false;
} };
(function () { (function () {
if (isIE) { if ( $.Browser.vendor == $.BROWSERS.IE ) {
$.addEvent( document, "mousedown", onGlobalMouseDown, false ); $.addEvent( document, "mousedown", onGlobalMouseDown, false );
$.addEvent( document, "mouseup", onGlobalMouseUp, false ); $.addEvent( document, "mouseup", onGlobalMouseUp, false );
} else { } else {
@ -3962,9 +4058,9 @@ function transform( stiffness, x ) {
* @property {String} url The URL of this tile's image. * @property {String} url The URL of this tile's image.
* @property {Boolean} loaded Is this tile loaded? * @property {Boolean} loaded Is this tile loaded?
* @property {Boolean} loading Is this tile loading * @property {Boolean} loading Is this tile loading
* @property {Element} elmt The HTML element for this tile * @property {Element} element The HTML element for this tile
* @property {Image} image The Image object for this tile * @property {Image} image The Image object for this tile
* @property {String} style The alias of this.elmt.style. * @property {String} style The alias of this.element.style.
* @property {String} position This tile's position on screen, in pixels. * @property {String} position This tile's position on screen, in pixels.
* @property {String} size This tile's size on screen, in pixels * @property {String} size This tile's size on screen, in pixels
* @property {String} blendStart The start time of this tile's blending * @property {String} blendStart The start time of this tile's blending
@ -3984,7 +4080,7 @@ $.Tile = function(level, x, y, bounds, exists, url) {
this.loaded = false; this.loaded = false;
this.loading = false; this.loading = false;
this.elmt = null; this.element = null;
this.image = null; this.image = null;
this.style = null; this.style = null;
@ -4029,26 +4125,26 @@ $.Tile.prototype = {
return; return;
} }
if ( !this.elmt ) { if ( !this.element ) {
this.elmt = $.makeNeutralElement("img"); this.element = $.makeNeutralElement("img");
this.elmt.src = this.url; this.element.src = this.url;
this.style = this.elmt.style; this.style = this.element.style;
this.style.position = "absolute"; this.style.position = "absolute";
this.style.msInterpolationMode = "nearest-neighbor"; this.style.msInterpolationMode = "nearest-neighbor";
} }
if ( this.elmt.parentNode != container ) { if ( this.element.parentNode != container ) {
container.appendChild( this.elmt ); container.appendChild( this.element );
} }
this.elmt.style.left = position.x + "px"; this.element.style.left = position.x + "px";
this.elmt.style.top = position.y + "px"; this.element.style.top = position.y + "px";
this.elmt.style.width = size.x + "px"; this.element.style.width = size.x + "px";
this.elmt.style.height = size.y + "px"; this.element.style.height = size.y + "px";
$.setElementOpacity( this.elmt, this.opacity ); $.setElementOpacity( this.element, this.opacity );
}, },
@ -4079,11 +4175,11 @@ $.Tile.prototype = {
* @function * @function
*/ */
unload: function() { unload: function() {
if ( this.elmt && this.elmt.parentNode ) { if ( this.element && this.element.parentNode ) {
this.elmt.parentNode.removeChild( this.elmt ); this.element.parentNode.removeChild( this.element );
} }
this.elmt = null; this.element = null;
this.image = null; this.image = null;
this.loaded = false; this.loaded = false;
this.loading = false; this.loading = false;
@ -4116,8 +4212,8 @@ $.Tile.prototype = {
* An Overlay provides a * An Overlay provides a
* @class * @class
*/ */
$.Overlay = function( elmt, location, placement ) { $.Overlay = function( element, location, placement ) {
this.elmt = elmt; this.element = element;
this.scales = location instanceof $.Rect; this.scales = location instanceof $.Rect;
this.bounds = new $.Rect( this.bounds = new $.Rect(
location.x, location.x,
@ -4133,7 +4229,7 @@ $.Tile.prototype = {
location.width, location.width,
location.height location.height
); );
this.style = elmt.style; this.style = element.style;
// rects are always top-left // rects are always top-left
this.placement = location instanceof $.Point ? this.placement = location instanceof $.Point ?
placement : placement :
@ -4179,7 +4275,7 @@ $.Tile.prototype = {
}, },
destroy: function() { destroy: function() {
var element = this.elmt, var element = this.element,
style = this.style; style = this.style;
if ( element.parentNode ) { if ( element.parentNode ) {
@ -4197,7 +4293,7 @@ $.Tile.prototype = {
}, },
drawHTML: function( container ) { drawHTML: function( container ) {
var element = this.elmt, var element = this.element,
style = this.style, style = this.style,
scales = this.scales, scales = this.scales,
position, position,
@ -4290,7 +4386,7 @@ var QUOTA = 100,
* @property {Number} lastResetTime - Last time for which the drawer was reset. * @property {Number} lastResetTime - Last time for which the drawer was reset.
* @property {Boolean} midUpdate - Is the drawer currently updating the viewport? * @property {Boolean} midUpdate - Is the drawer currently updating the viewport?
* @property {Boolean} updateAgain - Does the drawer need to update the viewort again? * @property {Boolean} updateAgain - Does the drawer need to update the viewort again?
* @property {Element} elmt - DEPRECATED Alias for container. * @property {Element} element - DEPRECATED Alias for container.
*/ */
$.Drawer = function( source, viewport, element ) { $.Drawer = function( source, viewport, element ) {
@ -4311,7 +4407,7 @@ $.Drawer = function( source, viewport, element ) {
this.lastResetTime = 0; this.lastResetTime = 0;
this.midUpdate = false; this.midUpdate = false;
this.updateAgain = true; this.updateAgain = true;
this.elmt = this.container; this.element = this.container;
this.canvas.style.width = "100%"; this.canvas.style.width = "100%";
this.canvas.style.height = "100%"; this.canvas.style.height = "100%";
@ -5049,7 +5145,7 @@ function resetCoverage( coverage, level ) {
function getOverlayIndex( overlays, element ) { function getOverlayIndex( overlays, element ) {
var i; var i;
for ( i = overlays.length - 1; i >= 0; i-- ) { for ( i = overlays.length - 1; i >= 0; i-- ) {
if ( overlays[ i ].elmt == element ) { if ( overlays[ i ].element == element ) {
return i; return i;
} }
} }

View File

@ -42,7 +42,7 @@ var QUOTA = 100,
* @property {Number} lastResetTime - Last time for which the drawer was reset. * @property {Number} lastResetTime - Last time for which the drawer was reset.
* @property {Boolean} midUpdate - Is the drawer currently updating the viewport? * @property {Boolean} midUpdate - Is the drawer currently updating the viewport?
* @property {Boolean} updateAgain - Does the drawer need to update the viewort again? * @property {Boolean} updateAgain - Does the drawer need to update the viewort again?
* @property {Element} elmt - DEPRECATED Alias for container. * @property {Element} element - DEPRECATED Alias for container.
*/ */
$.Drawer = function( source, viewport, element ) { $.Drawer = function( source, viewport, element ) {
@ -63,7 +63,7 @@ $.Drawer = function( source, viewport, element ) {
this.lastResetTime = 0; this.lastResetTime = 0;
this.midUpdate = false; this.midUpdate = false;
this.updateAgain = true; this.updateAgain = true;
this.elmt = this.container; this.element = this.container;
this.canvas.style.width = "100%"; this.canvas.style.width = "100%";
this.canvas.style.height = "100%"; this.canvas.style.height = "100%";
@ -801,7 +801,7 @@ function resetCoverage( coverage, level ) {
function getOverlayIndex( overlays, element ) { function getOverlayIndex( overlays, element ) {
var i; var i;
for ( i = overlays.length - 1; i >= 0; i-- ) { for ( i = overlays.length - 1; i >= 0; i-- ) {
if ( overlays[ i ].elmt == element ) { if ( overlays[ i ].element == element ) {
return i; return i;
} }
} }

View File

@ -9,8 +9,7 @@
return; return;
} }
var isIE = $.Browser.vendor == $.BROWSERS.IE, var buttonDownAny = false,
buttonDownAny = false,
ieCapturingAny = false, ieCapturingAny = false,
ieTrackersActive = {}, // dictionary from hash to MouseTracker ieTrackersActive = {}, // dictionary from hash to MouseTracker
ieTrackersCapturing = []; // list of trackers interested in capture ieTrackersCapturing = []; // list of trackers interested in capture
@ -18,252 +17,335 @@
/** /**
* @class * @class
*/ */
$.MouseTracker = function (elmt, clickTimeThreshold, clickDistThreshold) { $.MouseTracker = function ( element, clickTimeThreshold, clickDistThreshold ) {
//Start Thatcher - TODO: remove local function definitions in favor of //Start Thatcher - TODO: remove local function definitions in favor of
// - a global closure for MouseTracker so the number // - a global closure for MouseTracker so the number
// - of Viewers has less memory impact. Also use // - of Viewers has less memory impact. Also use
// - prototype pattern instead of Singleton pattern. // - prototype pattern instead of Singleton pattern.
//End Thatcher //End Thatcher
var self = this,
ieSelf = null,
hash = Math.random(), // a unique hash for this tracker this.hash = Math.random(); // a unique hash for this tracker
elmt = $.getElement(elmt), this.element = $.getElement( element );
tracking = false, this.tracking = false;
capturing = false, this.capturing = false;
buttonDownElmt = false, this.buttonDownElement = false;
insideElmt = false, this.insideElement = false;
lastPoint = null, // position of last mouse down/move this.lastPoint = null; // position of last mouse down/move
lastMouseDownTime = null, // time of last mouse down this.lastMouseDownTime = null; // time of last mouse down
lastMouseDownPoint = null, // position of last mouse down this.lastMouseDownPoint = null; // position of last mouse down
clickTimeThreshold = clickTimeThreshold, this.clickTimeThreshold = clickTimeThreshold;
clickDistThreshold = clickDistThreshold; this.clickDistThreshold = clickDistThreshold;
this.target = elmt; this.target = element;
this.enterHandler = null; // function(tracker, position, buttonDownElmt, buttonDownAny) this.enterHandler = null; // function(tracker, position, buttonDownElement, buttonDownAny)
this.exitHandler = null; // function(tracker, position, buttonDownElmt, buttonDownAny) this.exitHandler = null; // function(tracker, position, buttonDownElement, buttonDownAny)
this.pressHandler = null; // function(tracker, position) this.pressHandler = null; // function(tracker, position)
this.releaseHandler = null; // function(tracker, position, insideElmtPress, insideElmtRelease) this.releaseHandler = null; // function(tracker, position, insideElementPress, insideElementRelease)
this.scrollHandler = null; // function(tracker, position, scroll, shift) this.scrollHandler = null; // function(tracker, position, scroll, shift)
this.clickHandler = null; // function(tracker, position, quick, shift) this.clickHandler = null; // function(tracker, position, quick, shift)
this.dragHandler = null; // function(tracker, position, delta, shift) this.dragHandler = null; // function(tracker, position, delta, shift)
(function () { this.delegates = {
ieSelf = { "mouseover": $.delegate(this, this.onMouseOver),
hasMouse: hasMouse, "mouseout": $.delegate(this, this.onMouseOut),
onMouseOver: onMouseOver, "mousedown": $.delegate(this, this.onMouseDown),
onMouseOut: onMouseOut, "mouseup": $.delegate(this, this.onMouseUp),
onMouseUp: onMouseUp, "click": $.delegate(this, this.onMouseClick),
onMouseMove: onMouseMove "DOMMouseScroll": $.delegate(this, this.onMouseWheelSpin),
}; "mousewheel": $.delegate(this, this.onMouseWheelSpin),
})(); "mouseupie": $.delegate(this, this.onMouseUpIE),
"mousemoveie": $.delegate(this, this.onMouseMoveIE),
"mouseupwindow": $.delegate(this, this.onMouseUpWindow),
this.isTracking = function () { "mousemove": $.delegate(this, this.onMouseMove)
return tracking;
}; };
this.setTracking = function (track) { };
$.MouseTracker.prototype = {
/**
* @method
*/
isTracking: function () {
return this.tracking;
},
/**
* @method
*/
setTracking: function ( track ) {
if ( track ) { if ( track ) {
startTracking(); this.startTracking();
} else { } else {
stopTracking(); this.stopTracking();
} }
}; },
function startTracking() { /**
if (!tracking) { * @method
$.addEvent(elmt, "mouseover", onMouseOver, false); */
$.addEvent(elmt, "mouseout", onMouseOut, false); startTracking: function() {
$.addEvent(elmt, "mousedown", onMouseDown, false); if ( !this.tracking ) {
$.addEvent(elmt, "mouseup", onMouseUp, false); $.addEvent( this.element, "mouseover", this.delegates["mouseover"], false);
$.addEvent(elmt, "click", onMouseClick, false); $.addEvent( this.element, "mouseout", this.delegates["mouseout"], false);
$.addEvent(elmt, "DOMMouseScroll", onMouseWheelSpin, false); $.addEvent( this.element, "mousedown", this.delegates["mousedown"], false);
$.addEvent(elmt, "mousewheel", onMouseWheelSpin, false); // Firefox $.addEvent( this.element, "mouseup", this.delegates["mouseup"], false);
$.addEvent( this.element, "click", this.delegates["click"], false);
$.addEvent( this.element, "DOMMouseScroll", this.delegates["DOMMouseScroll"], false);
$.addEvent( this.element, "mousewheel", this.delegates["mousewheel"], false); // Firefox
tracking = true; this.tracking = true;
ieTrackersActive[hash] = ieSelf; ieTrackersActive[ this.hash ] = this;
}
} }
},
function stopTracking() { /**
if (tracking) { * @method
$.removeEvent(elmt, "mouseover", onMouseOver, false); */
$.removeEvent(elmt, "mouseout", onMouseOut, false); stopTracking: function() {
$.removeEvent(elmt, "mousedown", onMouseDown, false); if ( this.tracking ) {
$.removeEvent(elmt, "mouseup", onMouseUp, false); $.removeEvent( this.element, "mouseover", this.delegates["mouseover"], false);
$.removeEvent(elmt, "click", onMouseClick, false); $.removeEvent( this.element, "mouseout", this.delegates["mouseout"], false);
$.removeEvent(elmt, "DOMMouseScroll", onMouseWheelSpin, false); $.removeEvent( this.element, "mousedown", this.delegates["mousedown"], false);
$.removeEvent(elmt, "mousewheel", onMouseWheelSpin, false); $.removeEvent( this.element, "mouseup", this.delegates["mouseup"], false);
$.removeEvent( this.element, "click", this.delegates["click"], false);
$.removeEvent( this.element, "DOMMouseScroll", this.delegates["DOMMouseScroll"], false);
$.removeEvent( this.element, "mousewheel", this.delegates["mousewheel"], false);
releaseMouse(); this.releaseMouse();
tracking = false; this.tracking = false;
delete ieTrackersActive[hash]; delete ieTrackersActive[ this.hash ];
}
} }
},
function captureMouse() { /**
if (!capturing) { * @method
if (isIE) { */
$.removeEvent(elmt, "mouseup", onMouseUp, false); captureMouse: function() {
$.addEvent(elmt, "mouseup", onMouseUpIE, true); if ( !this.capturing ) {
$.addEvent(elmt, "mousemove", onMouseMoveIE, true); if ( $.Browser.vendor == $.BROWSERS.IE ) {
$.removeEvent( this.element, "mouseup", this.delegates["mouseup"], false );
$.addEvent( this.element, "mouseup", this.delegates["mouseupie"], true );
$.addEvent( this.element, "mousemove", this.delegates["mousemoveie"], true );
} else { } else {
$.addEvent(window, "mouseup", onMouseUpWindow, true); $.addEvent( window, "mouseup", this.delegates["mouseupwindow"], true );
$.addEvent(window, "mousemove", onMouseMove, true); $.addEvent( window, "mousemove", this.delegates["mousemove"], true );
} }
capturing = true; this.capturing = true;
}
} }
},
function releaseMouse() {
if (capturing) { /**
if (isIE) { * @method
$.removeEvent(elmt, "mousemove", onMouseMoveIE, true); */
$.removeEvent(elmt, "mouseup", onMouseUpIE, true); releaseMouse: function() {
$.addEvent(elmt, "mouseup", onMouseUp, false); if ( this.capturing ) {
if ( $.Browser.vendor == $.BROWSERS.IE ) {
$.removeEvent( this.element, "mousemove", this.delegates["mousemoveie"], true );
$.removeEvent( this.element, "mouseup", this.delegates["mouseupie"], true );
$.addEvent( this.element, "mouseup", this.delegates["mouseup"], false );
} else { } else {
$.removeEvent(window, "mousemove", onMouseMove, true); $.removeEvent( window, "mousemove", this.delegates["mousemove"], true );
$.removeEvent(window, "mouseup", onMouseUpWindow, true); $.removeEvent( window, "mouseup", this.delegates["mouseupwindow"], true );
} }
capturing = false; this.capturing = false;
}
} }
},
function triggerOthers(eventName, event) { /**
var trackers = ieTrackersActive; * @method
for (var otherHash in trackers) { */
if (trackers.hasOwnProperty(otherHash) && hash != otherHash) { triggerOthers: function( eventName, event ) {
var trackers = ieTrackersActive,
otherHash;
for ( otherHash in trackers ) {
if ( trackers.hasOwnProperty( otherHash ) && this.hash != otherHash ) {
trackers[ otherHash ][ eventName ]( event ); trackers[ otherHash ][ eventName ]( event );
} }
} }
} },
function hasMouse() { /**
return insideElmt; * @method
} */
hasMouse: function() {
return this.insideElement;
},
function onMouseOver(event) { /**
* @method
*/
onMouseOver: function( event ) {
var event = $.getEvent( event ); var event = $.getEvent( event );
if (isIE && capturing && !isChild(event.srcElement, elmt)) { if ( $.Browser.vendor == $.BROWSERS.IE &&
triggerOthers("onMouseOver", event); this.capturing &&
!isChild( event.srcElement, this.element ) ) {
this.triggerOthers( "onMouseOver", event );
} }
var to = event.target ? event.target : event.srcElement; var to = event.target ?
var from = event.relatedTarget ? event.relatedTarget : event.fromElement; event.target :
if (!isChild(elmt, to) || isChild(elmt, from)) { event.srcElement,
from = event.relatedTarget ?
event.relatedTarget :
event.fromElement;
if ( !isChild( this.element, to ) || isChild( this.element, from ) ) {
return; return;
} }
insideElmt = true; this.insideElement = true;
if (typeof (self.enterHandler) == "function") { if ( typeof( this.enterHandler ) == "function") {
try { try {
self.enterHandler(self, getMouseRelative(event, elmt), this.enterHandler(
buttonDownElmt, buttonDownAny); this,
getMouseRelative( event, this.element ),
this.buttonDownElement,
buttonDownAny
);
} catch ( e ) { } catch ( e ) {
$.console.error(e.name + $.console.error(
" while executing enter handler: " + e.message, e); e.name + " while executing enter handler: " + e.message,
} e
);
} }
} }
},
function onMouseOut(event) { /**
* @method
*/
onMouseOut: function( event ) {
var event = $.getEvent( event ); var event = $.getEvent( event );
if (isIE && capturing && !isChild(event.srcElement, elmt)) { if ( $.Browser.vendor == $.BROWSERS.IE &&
triggerOthers("onMouseOut", event); this.capturing &&
!isChild( event.srcElement, this.element ) ) {
this.triggerOthers( "onMouseOut", event );
} }
var from = event.target ? event.target : event.srcElement; var from = event.target ?
var to = event.relatedTarget ? event.relatedTarget : event.toElement; event.target :
if (!isChild(elmt, from) || isChild(elmt, to)) { event.srcElement,
to = event.relatedTarget ?
event.relatedTarget :
event.toElement;
if ( !isChild( this.element, from ) || isChild( this.element, to ) ) {
return; return;
} }
insideElmt = false; this.insideElement = false;
if (typeof (self.exitHandler) == "function") { if ( typeof( this.exitHandler ) == "function" ) {
try { try {
self.exitHandler(self, getMouseRelative(event, elmt), this.exitHandler(
buttonDownElmt, buttonDownAny); this,
getMouseRelative( event, this.element ),
this.buttonDownElement,
buttonDownAny
);
} catch ( e ) { } catch ( e ) {
$.console.error(e.name + $.console.error(
" while executing exit handler: " + e.message, e); e.name + " while executing exit handler: " + e.message,
} e
);
} }
} }
},
function onMouseDown(event) { /**
* @method
* @inner
*/
onMouseDown: function( event ) {
var event = $.getEvent( event ); var event = $.getEvent( event );
if ( event.button == 2 ) { if ( event.button == 2 ) {
return; return;
} }
buttonDownElmt = true; this.buttonDownElement = true;
lastPoint = getMouseAbsolute(event); this.lastPoint = getMouseAbsolute( event );
lastMouseDownPoint = lastPoint; this.lastMouseDownPoint = this.lastPoint;
lastMouseDownTime = new Date().getTime(); this.lastMouseDownTime = new Date().getTime();
if (typeof (self.pressHandler) == "function") { if ( typeof( this.pressHandler ) == "function" ) {
try { try {
self.pressHandler(self, getMouseRelative(event, elmt)); this.pressHandler(
this,
getMouseRelative( event, this.element )
);
} catch (e) { } catch (e) {
$.console.error(e.name + $.console.error(
" while executing press handler: " + e.message, e); e.name + " while executing press handler: " + e.message,
e
);
} }
} }
if (self.pressHandler || self.dragHandler) { if ( this.pressHandler || this.dragHandler ) {
$.cancelEvent( event ); $.cancelEvent( event );
} }
if (!isIE || !ieCapturingAny) { if ( !( $.Browser.vendor == $.BROWSERS.IE ) || !ieCapturingAny ) {
captureMouse(); this.captureMouse();
ieCapturingAny = true; ieCapturingAny = true;
ieTrackersCapturing = [ieSelf]; // reset to empty & add us ieTrackersCapturing = [ this ]; // reset to empty & add us
} else if (isIE) { } else if ( $.Browser.vendor == $.BROWSERS.IE ) {
ieTrackersCapturing.push(ieSelf); // add us to the list ieTrackersCapturing.push( this ); // add us to the list
}
} }
},
function onMouseUp(event) { /**
var event = $.getEvent(event); * @method
var insideElmtPress = buttonDownElmt; */
var insideElmtRelease = insideElmt; onMouseUp: function( event ) {
var event = $.getEvent( event ),
insideElementPress = this.buttonDownElement,
insideElementRelease = this.insideElement;
if ( event.button == 2 ) { if ( event.button == 2 ) {
return; return;
} }
buttonDownElmt = false; this.buttonDownElement = false;
if (typeof (self.releaseHandler) == "function") { if ( typeof( this.releaseHandler ) == "function" ) {
try { try {
self.releaseHandler(self, getMouseRelative(event, elmt), this.releaseHandler(
insideElmtPress, insideElmtRelease); this,
getMouseRelative( event, this.element ),
insideElementPress,
insideElementRelease
);
} catch (e) { } catch (e) {
$.console.error(e.name + $.console.error(
" while executing release handler: " + e.message, e); e.name + " while executing release handler: " + e.message,
e
);
} }
} }
if (insideElmtPress && insideElmtRelease) { if ( insideElementPress && insideElementRelease ) {
handleMouseClick(event); this.handleMouseClick( event );
}
} }
},
/** /**
* @method
* Only triggered once by the deepest element that initially received * Only triggered once by the deepest element that initially received
* the mouse down event. We want to make sure THIS event doesn't bubble. * the mouse down event. We want to make sure THIS event doesn't bubble.
* Instead, we want to trigger the elements that initially received the * Instead, we want to trigger the elements that initially received the
@ -271,164 +353,178 @@
* inside them. Then, we want to release capture, and emulate a regular * inside them. Then, we want to release capture, and emulate a regular
* mouseup on the event that this event was meant for. * mouseup on the event that this event was meant for.
*/ */
function onMouseUpIE(event) { onMouseUpIE: function( event ) {
var event = $.getEvent(event); var event = $.getEvent( event ),
tracker,
i;
if ( event.button == 2 ) { if ( event.button == 2 ) {
return; return;
} }
for (var i = 0; i < ieTrackersCapturing.length; i++) { for ( i = 0; i < ieTrackersCapturing.length; i++ ) {
var tracker = ieTrackersCapturing[i]; tracker = ieTrackersCapturing[ i ];
if ( !tracker.hasMouse() ) { if ( !tracker.hasMouse() ) {
tracker.onMouseUp( event ); tracker.onMouseUp( event );
} }
} }
releaseMouse(); this.releaseMouse();
ieCapturingAny = false; ieCapturingAny = false;
event.srcElement.fireEvent("on" + event.type, event.srcElement.fireEvent(
document.createEventObject(event)); "on" + event.type,
document.createEventObject( event )
);
$.stopEvent( event ); $.stopEvent( event );
} },
/** /**
* @private * @method
* @inner
* Only triggered in W3C browsers by elements within which the mouse was * Only triggered in W3C browsers by elements within which the mouse was
* initially pressed, since they are now listening to the window for * initially pressed, since they are now listening to the window for
* mouseup during the capture phase. We shouldn't handle the mouseup * mouseup during the capture phase. We shouldn't handle the mouseup
* here if the mouse is still inside this element, since the regular * here if the mouse is still inside this element, since the regular
* mouseup handler will still fire. * mouseup handler will still fire.
*/ */
function onMouseUpWindow(event) { onMouseUpWindow: function( event ) {
if (!insideElmt) { if ( !this.insideElement ) {
onMouseUp(event); this.onMouseUp( event );
} }
releaseMouse(); this.releaseMouse();
} },
/** /**
* @private * @method
* @inner
*/ */
function onMouseClick(event) { onMouseClick: function( event ) {
if (self.clickHandler) { if ( this.clickHandler ) {
$.cancelEvent( event ); $.cancelEvent( event );
} }
} },
/** /**
* @private * @method
* @inner
*/ */
function onMouseWheelSpin(event) { onMouseWheelSpin: function( event ) {
var nDelta = 0; var nDelta = 0;
if ( !event ) { // For IE, access the global (window) event object if ( !event ) { // For IE, access the global (window) event object
event = window.event; event = window.event;
} }
if ( event.wheelDelta ) { // IE and Opera if ( event.wheelDelta ) { // IE and Opera
nDelta = event.wheelDelta; nDelta = event.wheelDelta;
if ( window.opera ) { // Opera has the values reversed if ( window.opera ) { // Opera has the values reversed
nDelta = -nDelta; nDelta = -nDelta;
} }
} } else if (event.detail) { // Mozilla FireFox
else if (event.detail) { // Mozilla FireFox
nDelta = -event.detail; nDelta = -event.detail;
} }
nDelta = nDelta > 0 ? 1 : -1; nDelta = nDelta > 0 ? 1 : -1;
if (typeof (self.scrollHandler) == "function") { if ( typeof( this.scrollHandler ) == "function" ) {
try { try {
self.scrollHandler(self, getMouseRelative(event, elmt), nDelta, event.shiftKey); this.scrollHandler(
} catch (e) { this,
$.console.error(e.name + getMouseRelative( event, this.element ),
" while executing scroll handler: " + e.message, e); nDelta,
}
$.cancelEvent(event);
}
}
/**
* @private
* @inner
*/
function handleMouseClick(event) {
var event = $.getEvent(event);
if (event.button == 2) {
return;
}
var time = new Date().getTime() - lastMouseDownTime;
var point = getMouseAbsolute(event);
var distance = lastMouseDownPoint.distanceTo(point);
var quick = time <= clickTimeThreshold &&
distance <= clickDistThreshold;
if (typeof (self.clickHandler) == "function") {
try {
self.clickHandler(self, getMouseRelative(event, elmt),
quick, event.shiftKey);
} catch (e) {
$.console.error(e.name +
" while executing click handler: " + e.message, e);
}
}
}
/**
* @private
* @inner
*/
function onMouseMove(event) {
var event = $.getEvent(event);
var point = getMouseAbsolute(event);
var delta = point.minus(lastPoint);
lastPoint = point;
if (typeof (self.dragHandler) == "function") {
try {
self.dragHandler(
self,
getMouseRelative( event, elmt ),
delta,
event.shiftKey event.shiftKey
); );
} catch (e) { } catch (e) {
$.console.error( $.console.error(
e.name + e.name + " while executing scroll handler: " + e.message,
" while executing drag handler: "
+ e.message,
e e
); );
} }
$.cancelEvent( event ); $.cancelEvent( event );
} }
}; },
/**
* @method
*/
handleMouseClick: function( event ) {
var event = $.getEvent( event );
if ( event.button == 2 ) {
return;
}
var time = new Date().getTime() - this.lastMouseDownTime;
var point = getMouseAbsolute( event );
var distance = this.lastMouseDownPoint.distanceTo( point );
var quick = (
time <= this.clickTimeThreshold
) && (
distance <= this.clickDistThreshold
);
if ( typeof( this.clickHandler ) == "function" ) {
try {
this.clickHandler(
this,
getMouseRelative( event, this.element ),
quick,
event.shiftKey
);
} catch ( e ) {
$.console.error(
e.name + " while executing click handler: " + e.message,
e
);
}
}
},
/**
* @method
*/
onMouseMove: function( event ) {
var event = $.getEvent( event );
var point = getMouseAbsolute( event );
var delta = point.minus( this.lastPoint );
this.lastPoint = point;
if ( typeof( this.dragHandler ) == "function" ) {
try {
this.dragHandler(
this,
getMouseRelative( event, this.element ),
delta,
event.shiftKey
);
} catch (e) {
$.console.error(
e.name + " while executing drag handler: " + e.message,
e
);
}
$.cancelEvent( event );
}
},
/** /**
* @private
* @inner
* Only triggered once by the deepest element that initially received * Only triggered once by the deepest element that initially received
* the mouse down event. Since no other element has captured the mouse, * the mouse down event. Since no other element has captured the mouse,
* we want to trigger the elements that initially received the mouse * we want to trigger the elements that initially received the mouse
* down event (including this one). * down event (including this one).
* @method
*/ */
function onMouseMoveIE(event) { onMouseMoveIE: function( event ) {
for (var i = 0; i < ieTrackersCapturing.length; i++) { var i;
for ( i = 0; i < ieTrackersCapturing.length; i++ ) {
ieTrackersCapturing[ i ].onMouseMove( event ); ieTrackersCapturing[ i ].onMouseMove( event );
} }
$.stopEvent( event ); $.stopEvent( event );
}; }
}; };
@ -438,35 +534,35 @@
*/ */
function getMouseAbsolute( event ) { function getMouseAbsolute( event ) {
return $.getMousePosition( event ); return $.getMousePosition( event );
} };
/** /**
* @private * @private
* @inner * @inner
*/ */
function getMouseRelative( event, elmt ) { function getMouseRelative( event, element ) {
var mouse = $.getMousePosition(event); var mouse = $.getMousePosition( event ),
var offset = $.getElementPosition(elmt); offset = $.getElementPosition( element );
return mouse.minus( offset ); return mouse.minus( offset );
} };
/** /**
* @private * @private
* @inner * @inner
* Returns true if elmtB is a child node of elmtA, or if they're equal. * Returns true if elementB is a child node of elementA, or if they're equal.
*/ */
function isChild( elmtA, elmtB ) { function isChild( elementA, elementB ) {
var body = document.body; var body = document.body;
while (elmtB && elmtA != elmtB && body != elmtB) { while ( elementB && elementA != elementB && body != elementB ) {
try { try {
elmtB = elmtB.parentNode; elementB = elementB.parentNode;
} catch (e) { } catch (e) {
return false; return false;
} }
} }
return elmtA == elmtB; return elementA == elementB;
} };
/** /**
* @private * @private
@ -474,7 +570,7 @@
*/ */
function onGlobalMouseDown() { function onGlobalMouseDown() {
buttonDownAny = true; buttonDownAny = true;
} };
/** /**
* @private * @private
@ -482,11 +578,11 @@
*/ */
function onGlobalMouseUp() { function onGlobalMouseUp() {
buttonDownAny = false; buttonDownAny = false;
} };
(function () { (function () {
if (isIE) { if ( $.Browser.vendor == $.BROWSERS.IE ) {
$.addEvent( document, "mousedown", onGlobalMouseDown, false ); $.addEvent( document, "mousedown", onGlobalMouseDown, false );
$.addEvent( document, "mouseup", onGlobalMouseUp, false ); $.addEvent( document, "mouseup", onGlobalMouseUp, false );
} else { } else {

View File

@ -512,7 +512,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
*/ */
getPageScroll: function() { getPageScroll: function() {
var result = new $.Point(), var result = new $.Point(),
docElmt = document.documentElement || {}, docElement = document.documentElement || {},
body = document.body || {}; body = document.body || {};
if ( typeof( window.pageXOffset ) == "number" ) { if ( typeof( window.pageXOffset ) == "number" ) {
@ -521,9 +521,9 @@ OpenSeadragon = window.OpenSeadragon || (function(){
} else if ( body.scrollLeft || body.scrollTop ) { } else if ( body.scrollLeft || body.scrollTop ) {
result.x = body.scrollLeft; result.x = body.scrollLeft;
result.y = body.scrollTop; result.y = body.scrollTop;
} else if ( docElmt.scrollLeft || docElmt.scrollTop ) { } else if ( docElement.scrollLeft || docElement.scrollTop ) {
result.x = docElmt.scrollLeft; result.x = docElement.scrollLeft;
result.y = docElmt.scrollTop; result.y = docElement.scrollTop;
} }
return result; return result;
@ -537,15 +537,15 @@ OpenSeadragon = window.OpenSeadragon || (function(){
*/ */
getWindowSize: function() { getWindowSize: function() {
var result = new $.Point(), var result = new $.Point(),
docElmt = document.documentElement || {}, docElement = document.documentElement || {},
body = document.body || {}; body = document.body || {};
if ( typeof( window.innerWidth ) == 'number' ) { if ( typeof( window.innerWidth ) == 'number' ) {
result.x = window.innerWidth; result.x = window.innerWidth;
result.y = window.innerHeight; result.y = window.innerHeight;
} else if ( docElmt.clientWidth || docElmt.clientHeight ) { } else if ( docElement.clientWidth || docElement.clientHeight ) {
result.x = docElmt.clientWidth; result.x = docElement.clientWidth;
result.y = docElmt.clientHeight; result.y = docElement.clientHeight;
} else if ( body.clientWidth || body.clientHeight ) { } else if ( body.clientWidth || body.clientHeight ) {
result.x = body.clientWidth; result.x = body.clientWidth;
result.y = body.clientHeight; result.y = body.clientHeight;

View File

@ -23,8 +23,8 @@
* An Overlay provides a * An Overlay provides a
* @class * @class
*/ */
$.Overlay = function( elmt, location, placement ) { $.Overlay = function( element, location, placement ) {
this.elmt = elmt; this.element = element;
this.scales = location instanceof $.Rect; this.scales = location instanceof $.Rect;
this.bounds = new $.Rect( this.bounds = new $.Rect(
location.x, location.x,
@ -40,7 +40,7 @@
location.width, location.width,
location.height location.height
); );
this.style = elmt.style; this.style = element.style;
// rects are always top-left // rects are always top-left
this.placement = location instanceof $.Point ? this.placement = location instanceof $.Point ?
placement : placement :
@ -86,7 +86,7 @@
}, },
destroy: function() { destroy: function() {
var element = this.elmt, var element = this.element,
style = this.style; style = this.style;
if ( element.parentNode ) { if ( element.parentNode ) {
@ -104,7 +104,7 @@
}, },
drawHTML: function( container ) { drawHTML: function( container ) {
var element = this.elmt, var element = this.element,
style = this.style, style = this.style,
scales = this.scales, scales = this.scales,
position, position,

View File

@ -22,9 +22,9 @@
* @property {String} url The URL of this tile's image. * @property {String} url The URL of this tile's image.
* @property {Boolean} loaded Is this tile loaded? * @property {Boolean} loaded Is this tile loaded?
* @property {Boolean} loading Is this tile loading * @property {Boolean} loading Is this tile loading
* @property {Element} elmt The HTML element for this tile * @property {Element} element The HTML element for this tile
* @property {Image} image The Image object for this tile * @property {Image} image The Image object for this tile
* @property {String} style The alias of this.elmt.style. * @property {String} style The alias of this.element.style.
* @property {String} position This tile's position on screen, in pixels. * @property {String} position This tile's position on screen, in pixels.
* @property {String} size This tile's size on screen, in pixels * @property {String} size This tile's size on screen, in pixels
* @property {String} blendStart The start time of this tile's blending * @property {String} blendStart The start time of this tile's blending
@ -44,7 +44,7 @@ $.Tile = function(level, x, y, bounds, exists, url) {
this.loaded = false; this.loaded = false;
this.loading = false; this.loading = false;
this.elmt = null; this.element = null;
this.image = null; this.image = null;
this.style = null; this.style = null;
@ -89,26 +89,26 @@ $.Tile.prototype = {
return; return;
} }
if ( !this.elmt ) { if ( !this.element ) {
this.elmt = $.makeNeutralElement("img"); this.element = $.makeNeutralElement("img");
this.elmt.src = this.url; this.element.src = this.url;
this.style = this.elmt.style; this.style = this.element.style;
this.style.position = "absolute"; this.style.position = "absolute";
this.style.msInterpolationMode = "nearest-neighbor"; this.style.msInterpolationMode = "nearest-neighbor";
} }
if ( this.elmt.parentNode != container ) { if ( this.element.parentNode != container ) {
container.appendChild( this.elmt ); container.appendChild( this.element );
} }
this.elmt.style.left = position.x + "px"; this.element.style.left = position.x + "px";
this.elmt.style.top = position.y + "px"; this.element.style.top = position.y + "px";
this.elmt.style.width = size.x + "px"; this.element.style.width = size.x + "px";
this.elmt.style.height = size.y + "px"; this.element.style.height = size.y + "px";
$.setElementOpacity( this.elmt, this.opacity ); $.setElementOpacity( this.element, this.opacity );
}, },
@ -139,11 +139,11 @@ $.Tile.prototype = {
* @function * @function
*/ */
unload: function() { unload: function() {
if ( this.elmt && this.elmt.parentNode ) { if ( this.element && this.element.parentNode ) {
this.elmt.parentNode.removeChild( this.elmt ); this.element.parentNode.removeChild( this.element );
} }
this.elmt = null; this.element = null;
this.image = null; this.image = null;
this.loaded = false; this.loaded = false;
this.loading = false; this.loading = false;