Revert "Bad sync"

This reverts commit 70a7e8090e13cc35b93e652d2bcd7f418af26fc1.
This commit is contained in:
Mark Salsbery 2013-08-26 15:47:21 -07:00
parent 04a0197dc7
commit f8ab315795
4 changed files with 694 additions and 707 deletions

View File

@ -32,11 +32,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
(function ($) { (function($){
/** /**
* For use by classes which want to support custom, non-browser events. * For use by classes which want to support custom, non-browser events.
* TODO: This is an awful name! This thing represents an "event source", * TODO: This is an aweful name! This thing represents an "event source",
* not an "event handler". PLEASE change the to EventSource. Also please * not an "event handler". PLEASE change the to EventSource. Also please
* change 'addHandler', 'removeHandler' and 'raiseEvent' to 'bind', * change 'addHandler', 'removeHandler' and 'raiseEvent' to 'bind',
* 'unbind', and 'trigger' respectively. Finally add a method 'one' which * 'unbind', and 'trigger' respectively. Finally add a method 'one' which
@ -44,26 +44,25 @@
* matches. * matches.
* @class * @class
*/ */
$.EventHandler = function () { $.EventHandler = function() {
this.events = {}; this.events = {};
}; };
$.EventHandler.prototype = { $.EventHandler.prototype = {
/** /**
* Add an event handler for a given event. * Add an event handler for a given event.
* @function * @function
* @param {String} eventName - Name of event to register. * @param {String} eventName - Name of event to register.
* @param {Function} handler - Function to call when event is triggered. * @param {Function} handler - Function to call when event is triggered.
* @param {Object} optional userData - Arbitrary object to be passed to the handler.
*/ */
addHandler: function (eventName, handler, userData) { addHandler: function( eventName, handler ) {
var events = this.events[eventName]; var events = this.events[ eventName ];
if (!events) { if( !events ){
this.events[eventName] = events = []; this.events[ eventName ] = events = [];
} }
if (handler && $.isFunction(handler)) { if( handler && $.isFunction( handler ) ){
events[events.length] = { handler: handler, userData: userData || null }; events[ events.length ] = handler;
} }
}, },
@ -73,20 +72,20 @@
* @param {String} eventName - Name of event for which the handler is to be removed. * @param {String} eventName - Name of event for which the handler is to be removed.
* @param {Function} handler - Function to be removed. * @param {Function} handler - Function to be removed.
*/ */
removeHandler: function (eventName, handler) { removeHandler: function( eventName, handler ) {
var events = this.events[eventName], var events = this.events[ eventName ],
handlers = [], handlers = [],
i; i;
if (!events) { if ( !events ){
return; return;
} }
if ($.isArray(events)) { if( $.isArray( events ) ){
for (i = 0; i < events.length; i++) { for( i = 0; i < events.length; i++ ){
if (events[i].handler !== handler) { if( events[ i ] !== handler ){
handlers.push(events[i]); handlers.push( events[ i ] );
} }
} }
this.events[eventName] = handlers; this.events[ eventName ] = handlers;
} }
}, },
@ -97,10 +96,10 @@
* @function * @function
* @param {String} eventName - Name of event for which all handlers are to be removed. * @param {String} eventName - Name of event for which all handlers are to be removed.
*/ */
removeAllHandlers: function (eventName) { removeAllHandlers: function( eventName ) {
if (eventName) { if (eventName){
this.events[eventName] = []; this.events[ eventName ] = [];
} else { } else{
for (var eventType in this.events) { for (var eventType in this.events) {
this.events[eventType] = []; this.events[eventType] = [];
} }
@ -108,25 +107,24 @@
}, },
/** /**
* Retrieve the list of all handlers registered for a given event. * Retrive the list of all handlers registered for a given event.
* @function * @function
* @param {String} eventName - Name of event to get handlers for. * @param {String} eventName - Name of event to get handlers for.
*/ */
getHandler: function (eventName) { getHandler: function( eventName ) {
var events = this.events[eventName]; var events = this.events[ eventName ];
if (!events || !events.length) { if ( !events || !events.length ){
return null; return null;
} }
events = events.length === 1 ? events = events.length === 1 ?
[events[0]] : [ events[ 0 ] ] :
Array.apply(null, events); Array.apply( null, events );
return function (source, args) { return function( source, args ) {
var i, var i,
length = events.length; length = events.length;
for (i = 0; i < length; i++) { for ( i = 0; i < length; i++ ) {
if (events[i]) { if( events[ i ] ){
args.userData = events[i].userData; events[ i ]( source, args );
events[i].handler(source, args);
} }
} }
}; };
@ -138,19 +136,19 @@
* @param {String} eventName - Name of event to register. * @param {String} eventName - Name of event to register.
* @param {Function} handler - Function to call when event is triggered. * @param {Function} handler - Function to call when event is triggered.
*/ */
raiseEvent: function (eventName, eventArgs) { raiseEvent: function( eventName, eventArgs ) {
//uncomment if you want to get a log of all events //uncomment if you want to get a log of all events
//$.console.log( eventName ); //$.console.log( eventName );
var handler = this.getHandler(eventName); var handler = this.getHandler( eventName );
if (handler) { if ( handler ) {
if (!eventArgs) { if ( !eventArgs ) {
eventArgs = {}; eventArgs = {};
} }
handler(this, eventArgs); handler( this, eventArgs );
} }
} }
}; };
} (OpenSeadragon)); }( OpenSeadragon ));

View File

@ -32,9 +32,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
(function ($) { (function( $ ){
/** /**
* The LegacyTileSource allows simple, traditional image pyramids to be loaded * The LegacyTileSource allows simple, traditional image pyramids to be loaded
* into an OpenSeadragon Viewer. Basically, this translates to the historically * into an OpenSeadragon Viewer. Basically, this translates to the historically
* common practice of starting with a 'master' image, maybe a tiff for example, * common practice of starting with a 'master' image, maybe a tiff for example,
@ -56,13 +56,13 @@
* @property {Number} maxLevel * @property {Number} maxLevel
* @property {Array} levels * @property {Array} levels
*/ */
$.LegacyTileSource = function (levels) { $.LegacyTileSource = function( levels ) {
var options, var options,
width, width,
height; height;
if ($.isArray(levels)) { if( $.isArray( levels ) ){
options = { options = {
type: 'legacy-image-pyramid', type: 'legacy-image-pyramid',
levels: levels levels: levels
@ -70,33 +70,25 @@
} }
//clean up the levels to make sure we support all formats //clean up the levels to make sure we support all formats
options.levels = filterFiles(options.levels); options.levels = filterFiles( options.levels );
width = options.levels[ options.levels.length - 1 ].width;
height = options.levels[ options.levels.length - 1 ].height;
if (options.levels.length > 0) { $.extend( true, options, {
width = options.levels[options.levels.length - 1].width;
height = options.levels[options.levels.length - 1].height;
}
else {
width = 0;
height = 0;
$.console.error("No supported image formats found");
}
$.extend(true, options, {
width: width, width: width,
height: height, height: height,
tileSize: Math.max(height, width), tileSize: Math.max( height, width ),
tileOverlap: 0, tileOverlap: 0,
minLevel: 0, minLevel: 0,
maxLevel: options.levels.length > 0 ? options.levels.length - 1 : 0 maxLevel: options.levels.length - 1
}); });
$.TileSource.apply(this, [options]); $.TileSource.apply( this, [ options ] );
this.levels = options.levels; this.levels = options.levels;
}; };
$.extend($.LegacyTileSource.prototype, $.TileSource.prototype, { $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, {
/** /**
* Determine if the data and/or url imply the image service is supported by * Determine if the data and/or url imply the image service is supported by
* this tile source. * this tile source.
@ -105,7 +97,7 @@
* @param {Object|Array} data * @param {Object|Array} data
* @param {String} optional - url * @param {String} optional - url
*/ */
supports: function (data, url) { supports: function( data, url ){
return ( return (
data.type && data.type &&
"legacy-image-pyramid" == data.type "legacy-image-pyramid" == data.type
@ -125,17 +117,17 @@
* @return {Object} options - A dictionary of keyword arguments sufficient * @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile sources constructor. * to configure this tile sources constructor.
*/ */
configure: function (configuration, dataUrl) { configure: function( configuration, dataUrl ){
var options; var options;
if (!$.isPlainObject(configuration)) { if( !$.isPlainObject(configuration) ){
options = configureFromXML(this, configuration); options = configureFromXML( this, configuration );
} else { }else{
options = configureFromObject(this, configuration); options = configureFromObject( this, configuration );
} }
return options; return options;
@ -147,12 +139,12 @@
* @name OpenSeadragon.LegacyTileSource.prototype.getLevelScale * @name OpenSeadragon.LegacyTileSource.prototype.getLevelScale
* @param {Number} level * @param {Number} level
*/ */
getLevelScale: function (level) { getLevelScale: function( level ) {
var levelScale = NaN; var levelScale = NaN;
if (this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel) { if ( level >= this.minLevel && level <= this.maxLevel ){
levelScale = levelScale =
this.levels[level].width / this.levels[ level ].width /
this.levels[this.maxLevel].width; this.levels[ this.maxLevel ].width;
} }
return levelScale; return levelScale;
}, },
@ -162,12 +154,12 @@
* @name OpenSeadragon.LegacyTileSource.prototype.getNumTiles * @name OpenSeadragon.LegacyTileSource.prototype.getNumTiles
* @param {Number} level * @param {Number} level
*/ */
getNumTiles: function (level) { getNumTiles: function( level ) {
var scale = this.getLevelScale(level); var scale = this.getLevelScale( level );
if (scale) { if ( scale ){
return new $.Point(1, 1); return new $.Point( 1, 1 );
} else { } else {
return new $.Point(0, 0); return new $.Point( 0, 0 );
} }
}, },
@ -177,8 +169,8 @@
* @param {Number} level * @param {Number} level
* @param {OpenSeadragon.Point} point * @param {OpenSeadragon.Point} point
*/ */
getTileAtPoint: function (level, point) { getTileAtPoint: function( level, point ) {
return new $.Point(0, 0); return new $.Point( 0, 0 );
}, },
@ -194,63 +186,60 @@
* @param {Number} y * @param {Number} y
* @throws {Error} * @throws {Error}
*/ */
getTileUrl: function (level, x, y) { getTileUrl: function( level, x, y ) {
var url = null; var url = null;
if (this.levels.length > 0 && level >= this.minLevel && level <= this.maxLevel) { if( level >= this.minLevel && level <= this.maxLevel ){
url = this.levels[level].url; url = this.levels[ level ].url;
} }
return url; return url;
} }
}); });
/** /**
* This method removes any files from the Array which dont conform to our * This method removes any files from the Array which dont conform to our
* basic requirements for a 'level' in the LegacyTileSource. * basic requirements for a 'level' in the LegacyTileSource.
* @private * @private
* @inner * @inner
* @function * @function
*/ */
function filterFiles(files) { function filterFiles( files ){
var filtered = [], var filtered = [],
file, file,
i; i;
for (i = 0; i < files.length; i++) { for( i = 0; i < files.length; i++ ){
file = files[i]; file = files[ i ];
if (file.height && if( file.height &&
file.width && file.width &&
file.url && ( file.url && (
file.url.toLowerCase().match(/^.*\.(png|jpg|jpeg|gif)$/) || ( file.url.toLowerCase().match(/^.*\.(png|jpg|jpeg|gif)$/) || (
file.mimetype && file.mimetype &&
file.mimetype.toLowerCase().match(/^.*\/(png|jpg|jpeg|gif)$/) file.mimetype.toLowerCase().match(/^.*\/(png|jpg|jpeg|gif)$/)
) )
)) { ) ){
//This is sufficient to serve as a level //This is sufficient to serve as a level
filtered.push({ filtered.push({
url: file.url, url: file.url,
width: Number(file.width), width: Number( file.width ),
height: Number(file.height) height: Number( file.height )
}); });
} }
else {
$.console.error('Unsupported image format: %s', file.url ? file.url : '<no URL>');
}
} }
return filtered.sort(function (a, b) { return filtered.sort(function(a,b){
return a.height - b.height; return a.height - b.height;
}); });
} }
/** /**
* @private * @private
* @inner * @inner
* @function * @function
*/ */
function configureFromXML(tileSource, xmlDoc) { function configureFromXML( tileSource, xmlDoc ){
if (!xmlDoc || !xmlDoc.documentElement) { if ( !xmlDoc || !xmlDoc.documentElement ) {
throw new Error($.getString("Errors.Xml")); throw new Error( $.getString( "Errors.Xml" ) );
} }
var root = xmlDoc.documentElement, var root = xmlDoc.documentElement,
@ -260,50 +249,50 @@
level, level,
i; i;
if (rootName == "image") { if ( rootName == "image" ) {
try { try {
conf = { conf = {
type: root.getAttribute("type"), type: root.getAttribute( "type" ),
levels: [] levels: []
}; };
levels = root.getElementsByTagName("level"); levels = root.getElementsByTagName( "level" );
for (i = 0; i < levels.length; i++) { for ( i = 0; i < levels.length; i++ ) {
level = levels[i]; level = levels[ i ];
conf.levels.push({ conf.levels .push({
url: level.getAttribute("url"), url: level.getAttribute( "url" ),
width: parseInt(level.getAttribute("width"), 10), width: parseInt( level.getAttribute( "width" ), 10 ),
height: parseInt(level.getAttribute("height"), 10) height: parseInt( level.getAttribute( "height" ), 10 )
}); });
} }
return configureFromObject(tileSource, conf); return configureFromObject( tileSource, conf );
} catch (e) { } catch ( e ) {
throw (e instanceof Error) ? throw (e instanceof Error) ?
e : e :
new Error('Unknown error parsing Legacy Image Pyramid XML.'); new Error( 'Unknown error parsing Legacy Image Pyramid XML.' );
} }
} else if (rootName == "collection") { } else if ( rootName == "collection" ) {
throw new Error('Legacy Image Pyramid Collections not yet supported.'); throw new Error( 'Legacy Image Pyramid Collections not yet supported.' );
} else if (rootName == "error") { } else if ( rootName == "error" ) {
throw new Error('Error: ' + xmlDoc); throw new Error( 'Error: ' + xmlDoc );
} }
throw new Error('Unknown element ' + rootName); throw new Error( 'Unknown element ' + rootName );
} }
/** /**
* @private * @private
* @inner * @inner
* @function * @function
*/ */
function configureFromObject(tileSource, configuration) { function configureFromObject( tileSource, configuration ){
return configuration.levels; return configuration.levels;
} }
} (OpenSeadragon)); }( OpenSeadragon ));

View File

@ -32,10 +32,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
(function ($) { (function( $ ){
/** /**
* The TileSource contains the most basic implementation required to create a * The TileSource contains the most basic implementation required to create a
* smooth transition between layer in an image pyramid. It has only a single key * smooth transition between layer in an image pyramid. It has only a single key
* interface that must be implemented to complete it key functionality: * interface that must be implemented to complete it key functionality:
@ -83,15 +83,15 @@
* @property {Number} maxLevel * @property {Number} maxLevel
* The maximum pyramid level this tile source supports or should attempt to load. * The maximum pyramid level this tile source supports or should attempt to load.
*/ */
$.TileSource = function (width, height, tileSize, tileOverlap, minLevel, maxLevel) { $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) {
var callback = null, var callback = null,
args = arguments, args = arguments,
options, options,
i; i;
if ($.isPlainObject(width)) { if( $.isPlainObject( width ) ){
options = width; options = width;
} else { }else{
options = { options = {
width: args[0], width: args[0],
height: args[1], height: args[1],
@ -104,32 +104,32 @@
//Tile sources supply some events, namely 'ready' when they must be configured //Tile sources supply some events, namely 'ready' when they must be configured
//by asyncronously fetching their configuration data. //by asyncronously fetching their configuration data.
$.EventHandler.call(this); $.EventHandler.call( this );
//we allow options to override anything we dont treat as //we allow options to override anything we dont treat as
//required via idiomatic options or which is functionally //required via idiomatic options or which is functionally
//set depending on the state of the readiness of this tile //set depending on the state of the readiness of this tile
//source //source
$.extend(true, this, options); $.extend( true, this, options );
//Any functions that are passed as arguments are bound to the ready callback //Any functions that are passed as arguments are bound to the ready callback
/*jshint loopfunc:true*/ /*jshint loopfunc:true*/
for (i = 0; i < arguments.length; i++) { for( i = 0; i < arguments.length; i++ ){
if ($.isFunction(arguments[i])) { if( $.isFunction( arguments[i] ) ){
callback = arguments[i]; callback = arguments[ i ];
this.addHandler('ready', function (placeHolderSource, placeHolderArgs) { this.addHandler( 'ready', function( placeHolderSource, readySource ){
callback(placeHolderArgs.tileSource); callback( readySource );
}); });
//only one callback per constructor //only one callback per constructor
break; break;
} }
} }
if ('string' == $.type(arguments[0])) { if( 'string' == $.type( arguments[ 0 ] ) ){
//in case the getImageInfo method is overriden and/or implies an //in case the getImageInfo method is overriden and/or implies an
//async mechanism set some safe defaults first //async mechanism set some safe defaults first
this.aspectRatio = 1; this.aspectRatio = 1;
this.dimensions = new $.Point(10, 10); this.dimensions = new $.Point( 10, 10 );
this.tileSize = 0; this.tileSize = 0;
this.tileOverlap = 0; this.tileOverlap = 0;
this.minLevel = 0; this.minLevel = 0;
@ -137,75 +137,75 @@
this.ready = false; this.ready = false;
//configuration via url implies the extending class //configuration via url implies the extending class
//implements and 'configure' //implements and 'configure'
this.getImageInfo(arguments[0]); this.getImageInfo( arguments[ 0 ] );
} else { } else {
//explicit configuration via positional args in constructor //explicit configuration via positional args in constructor
//or the more idiomatic 'options' object //or the more idiomatic 'options' object
this.ready = true; this.ready = true;
this.aspectRatio = (options.width && options.height) ? this.aspectRatio = ( options.width && options.height ) ?
(options.width / options.height) : 1; ( options.width / options.height ) : 1;
this.dimensions = new $.Point(options.width, options.height); this.dimensions = new $.Point( options.width, options.height );
this.tileSize = options.tileSize ? options.tileSize : 0; this.tileSize = options.tileSize ? options.tileSize : 0;
this.tileOverlap = options.tileOverlap ? options.tileOverlap : 0; this.tileOverlap = options.tileOverlap ? options.tileOverlap : 0;
this.minLevel = options.minLevel ? options.minLevel : 0; this.minLevel = options.minLevel ? options.minLevel : 0;
this.maxLevel = (undefined !== options.maxLevel && null !== options.maxLevel) ? this.maxLevel = ( undefined !== options.maxLevel && null !== options.maxLevel ) ?
options.maxLevel : ( options.maxLevel : (
(options.width && options.height) ? Math.ceil( ( options.width && options.height ) ? Math.ceil(
Math.log(Math.max(options.width, options.height)) / Math.log( Math.max( options.width, options.height ) ) /
Math.log(2) Math.log( 2 )
) : 0 ) : 0
); );
if (callback && $.isFunction(callback)) { if( callback && $.isFunction( callback ) ){
callback(this); callback( this );
} }
} }
}; };
$.TileSource.prototype = { $.TileSource.prototype = {
/** /**
* @function * @function
* @param {Number} level * @param {Number} level
*/ */
getLevelScale: function (level) { getLevelScale: function( level ) {
// see https://github.com/openseadragon/openseadragon/issues/22 // see https://github.com/openseadragon/openseadragon/issues/22
// we use the tilesources implementation of getLevelScale to generate // we use the tilesources implementation of getLevelScale to generate
// a memoized re-implementation // a memoized re-implementation
var levelScaleCache = {}, var levelScaleCache = {},
i; i;
for (i = 0; i <= this.maxLevel; i++) { for( i = 0; i <= this.maxLevel; i++ ){
levelScaleCache[i] = 1 / Math.pow(2, this.maxLevel - i); levelScaleCache[ i ] = 1 / Math.pow(2, this.maxLevel - i);
} }
this.getLevelScale = function (_level) { this.getLevelScale = function( _level ){
return levelScaleCache[_level]; return levelScaleCache[ _level ];
}; };
return this.getLevelScale(level); return this.getLevelScale( level );
}, },
/** /**
* @function * @function
* @param {Number} level * @param {Number} level
*/ */
getNumTiles: function (level) { getNumTiles: function( level ) {
var scale = this.getLevelScale(level), var scale = this.getLevelScale( level ),
x = Math.ceil(scale * this.dimensions.x / this.tileSize), x = Math.ceil( scale * this.dimensions.x / this.tileSize ),
y = Math.ceil(scale * this.dimensions.y / this.tileSize); y = Math.ceil( scale * this.dimensions.y / this.tileSize );
return new $.Point(x, y); return new $.Point( x, y );
}, },
/** /**
* @function * @function
* @param {Number} level * @param {Number} level
*/ */
getPixelRatio: function (level) { getPixelRatio: function( level ) {
var imageSizeScaled = this.dimensions.times(this.getLevelScale(level)), var imageSizeScaled = this.dimensions.times( this.getLevelScale( level ) ),
rx = 1.0 / imageSizeScaled.x, rx = 1.0 / imageSizeScaled.x,
ry = 1.0 / imageSizeScaled.y; ry = 1.0 / imageSizeScaled.y;
@ -217,17 +217,17 @@
* @function * @function
* @param {Number} level * @param {Number} level
*/ */
getClosestLevel: function (rect) { getClosestLevel: function( rect ) {
var i, var i,
tilesPerSide = Math.floor(Math.max(rect.x, rect.y) / this.tileSize), tilesPerSide = Math.floor( Math.max( rect.x, rect.y ) / this.tileSize ),
tiles; tiles;
for (i = this.minLevel; i < this.maxLevel; i++) { for( i = this.minLevel; i < this.maxLevel; i++ ){
tiles = this.getNumTiles(i); tiles = this.getNumTiles( i );
if (Math.max(tiles.x, tiles.y) + 1 >= tilesPerSide) { if( Math.max( tiles.x, tiles.y ) + 1 >= tilesPerSide ){
break; break;
} }
} }
return Math.max(0, i - 1); return Math.max( 0, i - 1 );
}, },
/** /**
@ -235,12 +235,12 @@
* @param {Number} level * @param {Number} level
* @param {OpenSeadragon.Point} point * @param {OpenSeadragon.Point} point
*/ */
getTileAtPoint: function (level, point) { getTileAtPoint: function( level, point ) {
var pixel = point.times(this.dimensions.x).times(this.getLevelScale(level)), var pixel = point.times( this.dimensions.x ).times( this.getLevelScale(level ) ),
tx = Math.floor(pixel.x / this.tileSize), tx = Math.floor( pixel.x / this.tileSize ),
ty = Math.floor(pixel.y / this.tileSize); ty = Math.floor( pixel.y / this.tileSize );
return new $.Point(tx, ty); return new $.Point( tx, ty );
}, },
/** /**
@ -249,18 +249,18 @@
* @param {Number} x * @param {Number} x
* @param {Number} y * @param {Number} y
*/ */
getTileBounds: function (level, x, y) { getTileBounds: function( level, x, y ) {
var dimensionsScaled = this.dimensions.times(this.getLevelScale(level)), var dimensionsScaled = this.dimensions.times( this.getLevelScale( level ) ),
px = (x === 0) ? 0 : this.tileSize * x - this.tileOverlap, px = ( x === 0 ) ? 0 : this.tileSize * x - this.tileOverlap,
py = (y === 0) ? 0 : this.tileSize * y - this.tileOverlap, py = ( y === 0 ) ? 0 : this.tileSize * y - this.tileOverlap,
sx = this.tileSize + (x === 0 ? 1 : 2) * this.tileOverlap, sx = this.tileSize + ( x === 0 ? 1 : 2 ) * this.tileOverlap,
sy = this.tileSize + (y === 0 ? 1 : 2) * this.tileOverlap, sy = this.tileSize + ( y === 0 ? 1 : 2 ) * this.tileOverlap,
scale = 1.0 / dimensionsScaled.x; scale = 1.0 / dimensionsScaled.x;
sx = Math.min(sx, dimensionsScaled.x - px); sx = Math.min( sx, dimensionsScaled.x - px );
sy = Math.min(sy, dimensionsScaled.y - py); sy = Math.min( sy, dimensionsScaled.y - py );
return new $.Rect(px * scale, py * scale, sx * scale, sy * scale); return new $.Rect( px * scale, py * scale, sx * scale, sy * scale );
}, },
@ -271,7 +271,7 @@
* @param {String} url * @param {String} url
* @throws {Error} * @throws {Error}
*/ */
getImageInfo: function (url) { getImageInfo: function( url ) {
var _this = this, var _this = this,
callbackName, callbackName,
callback, callback,
@ -282,33 +282,33 @@
lastDot; lastDot;
if (url) { if( url ) {
urlParts = url.split('/'); urlParts = url.split( '/' );
filename = urlParts[urlParts.length - 1]; filename = urlParts[ urlParts.length - 1 ];
lastDot = filename.lastIndexOf('.'); lastDot = filename.lastIndexOf( '.' );
if (lastDot > -1) { if ( lastDot > -1 ) {
urlParts[urlParts.length - 1] = filename.slice(0, lastDot); urlParts[ urlParts.length - 1 ] = filename.slice( 0, lastDot );
} }
} }
callback = function (data) { callback = function( data ){
var $TileSource = $.TileSource.determineType(_this, data, url); var $TileSource = $.TileSource.determineType( _this, data, url );
if (!$TileSource) { if ( !$TileSource ) {
_this.raiseEvent('open-failed', { message: "Unable to load TileSource", source: url }); _this.raiseEvent( 'open-failed', { message: "Unable to load TileSource", source: url } );
return; return;
} }
options = $TileSource.prototype.configure.apply(_this, [data, url]); options = $TileSource.prototype.configure.apply( _this, [ data, url ]);
readySource = new $TileSource(options); readySource = new $TileSource( options );
_this.ready = true; _this.ready = true;
_this.raiseEvent('ready', { tileSource: readySource }); _this.raiseEvent( 'ready', readySource );
}; };
if (url.match(/\.js$/)) { if( url.match(/\.js$/) ){
//TODO: Its not very flexible to require tile sources to end jsonp //TODO: Its not very flexible to require tile sources to end jsonp
// request for info with a url that ends with '.js' but for // request for info with a url that ends with '.js' but for
// now it's the only way I see to distinguish uniformly. // now it's the only way I see to distinguish uniformly.
callbackName = url.split('/').pop().replace('.js', ''); callbackName = url.split( '/' ).pop().replace('.js','');
$.jsonp({ $.jsonp({
url: url, url: url,
async: false, async: false,
@ -317,11 +317,11 @@
}); });
} else { } else {
// request info via xhr asyncronously. // request info via xhr asyncronously.
$.makeAjaxRequest(url, function (xhr) { $.makeAjaxRequest( url, function( xhr ) {
var data = processResponse(xhr); var data = processResponse( xhr );
callback(data); callback( data );
}, function (xhr) { }, function ( xhr ) {
_this.raiseEvent('open-failed', { _this.raiseEvent( 'open-failed', {
message: "HTTP " + xhr.status + " attempting to load TileSource", message: "HTTP " + xhr.status + " attempting to load TileSource",
source: url source: url
}); });
@ -344,7 +344,7 @@
* from if any. * from if any.
* @return {Boolean} * @return {Boolean}
*/ */
supports: function (data, url) { supports: function( data, url ) {
return false; return false;
}, },
@ -363,8 +363,8 @@
* to configure this tile sources constructor. * to configure this tile sources constructor.
* @throws {Error} * @throws {Error}
*/ */
configure: function (data, url) { configure: function( data, url ) {
throw new Error("Method not implemented."); throw new Error( "Method not implemented." );
}, },
/** /**
@ -380,8 +380,8 @@
* @param {Number} y * @param {Number} y
* @throws {Error} * @throws {Error}
*/ */
getTileUrl: function (level, x, y) { getTileUrl: function( level, x, y ) {
throw new Error("Method not implemented."); throw new Error( "Method not implemented." );
}, },
/** /**
@ -390,8 +390,8 @@
* @param {Number} x * @param {Number} x
* @param {Number} y * @param {Number} y
*/ */
tileExists: function (level, x, y) { tileExists: function( level, x, y ) {
var numTiles = this.getNumTiles(level); var numTiles = this.getNumTiles( level );
return level >= this.minLevel && return level >= this.minLevel &&
level <= this.maxLevel && level <= this.maxLevel &&
x >= 0 && x >= 0 &&
@ -399,13 +399,13 @@
x < numTiles.x && x < numTiles.x &&
y < numTiles.y; y < numTiles.y;
} }
}; };
$.extend(true, $.TileSource.prototype, $.EventHandler.prototype); $.extend( true, $.TileSource.prototype, $.EventHandler.prototype );
/** /**
* Decides whether to try to process the response as xml, json, or hand back * Decides whether to try to process the response as xml, json, or hand back
* the text * the text
* @eprivate * @eprivate
@ -413,41 +413,41 @@
* @function * @function
* @param {XMLHttpRequest} xhr - the completed network request * @param {XMLHttpRequest} xhr - the completed network request
*/ */
function processResponse(xhr) { function processResponse( xhr ){
var responseText = xhr.responseText, var responseText = xhr.responseText,
status = xhr.status, status = xhr.status,
statusText, statusText,
data; data;
if (!xhr) { if ( !xhr ) {
throw new Error($.getString("Errors.Security")); throw new Error( $.getString( "Errors.Security" ) );
} else if (xhr.status !== 200 && xhr.status !== 0) { } else if ( xhr.status !== 200 && xhr.status !== 0 ) {
status = xhr.status; status = xhr.status;
statusText = (status == 404) ? statusText = ( status == 404 ) ?
"Not Found" : "Not Found" :
xhr.statusText; xhr.statusText;
throw new Error($.getString("Errors.Status", status, statusText)); throw new Error( $.getString( "Errors.Status", status, statusText ) );
} }
if (responseText.match(/\s*<.*/)) { if( responseText.match(/\s*<.*/) ){
try { try{
data = (xhr.responseXML && xhr.responseXML.documentElement) ? data = ( xhr.responseXML && xhr.responseXML.documentElement ) ?
xhr.responseXML : xhr.responseXML :
$.parseXml(responseText); $.parseXml( responseText );
} catch (e) { } catch (e){
data = xhr.responseText; data = xhr.responseText;
} }
} else if (responseText.match(/\s*[\{\[].*/)) { }else if( responseText.match(/\s*[\{\[].*/) ){
/*jshint evil:true*/ /*jshint evil:true*/
data = eval('(' + responseText + ')'); data = eval( '('+responseText+')' );
} else { }else{
data = responseText; data = responseText;
} }
return data; return data;
} }
/** /**
* Determines the TileSource Implementation by introspection of OpenSeadragon * Determines the TileSource Implementation by introspection of OpenSeadragon
* namespace, calling each TileSource implementation of 'isType' * namespace, calling each TileSource implementation of 'isType'
* @eprivate * @eprivate
@ -457,20 +457,20 @@
* @param {String} url - the url where the tile source configuration object was * @param {String} url - the url where the tile source configuration object was
* loaded from, if any. * loaded from, if any.
*/ */
$.TileSource.determineType = function (tileSource, data, url) { $.TileSource.determineType = function( tileSource, data, url ){
var property; var property;
for (property in OpenSeadragon) { for( property in OpenSeadragon ){
if (property.match(/.+TileSource$/) && if( property.match(/.+TileSource$/) &&
$.isFunction(OpenSeadragon[property]) && $.isFunction( OpenSeadragon[ property ] ) &&
$.isFunction(OpenSeadragon[property].prototype.supports) && $.isFunction( OpenSeadragon[ property ].prototype.supports ) &&
OpenSeadragon[property].prototype.supports.call(tileSource, data, url) OpenSeadragon[ property ].prototype.supports.call( tileSource, data, url )
) { ){
return OpenSeadragon[property]; return OpenSeadragon[ property ];
} }
} }
$.console.error("No TileSource was able to open %s %s", url, data); $.console.error( "No TileSource was able to open %s %s", url, data );
}; };
} (OpenSeadragon)); }( OpenSeadragon ));

View File

@ -1463,7 +1463,7 @@ function onCanvasDrag( tracker, position, delta, shift ) {
this.viewport.applyConstraints(); this.viewport.applyConstraints();
} }
} }
this.raiseEvent( 'canvas-drag', { this.raiseEvent( 'canvas-click', {
tracker: tracker, tracker: tracker,
position: position, position: position,
delta: delta, delta: delta,