diff --git a/src/openseadragon.js b/src/openseadragon.js index 07abcd42..81028d19 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -551,8 +551,11 @@ * If collectionMode is true, specifies the margin, in viewport coordinates, between each TiledImage. * * @property {String|Boolean} [crossOriginPolicy=false] - * Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will - * not use CORS, and the canvas will be tainted. + * Valid values are 'Anonymous', 'use-credentials', and false. If false, canvas requests will + * not use CORS, and the canvas will be tainted. + * + * @property {Boolean} [ajaxWithCredentials=false] + * Whether to set the withCredentials XHR flag for AJAX requests (when loading tile sources). * */ @@ -911,6 +914,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ tileHost: null, initialPage: 0, crossOriginPolicy: false, + ajaxWithCredentials: false, //PAN AND ZOOM SETTINGS AND CONSTRAINTS panHorizontal: true, @@ -1923,6 +1927,15 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ * @throws {Error} */ makeAjaxRequest: function( url, onSuccess, onError ) { + var withCredentials; + + if( $.isPlainObject( url ) ){ + onSuccess = url.success; + onError = url.error; + withCredentials = url.withCredentials; + url = url.url; + } + var protocol = $.getUrlProtocol( url ); var request = $.createAjaxRequest( protocol === "file:" ); @@ -1949,6 +1962,10 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ } }; + if (withCredentials) { + request.withCredentials = true; + } + try { request.open( "GET", url, true ); request.send( null ); diff --git a/src/tilesource.js b/src/tilesource.js index deecc742..8d6ab5fb 100644 --- a/src/tilesource.js +++ b/src/tilesource.js @@ -74,8 +74,9 @@ * The maximum level to attempt to load. */ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) { - var callback = null, - args = arguments, + var _this = this; + + var args = arguments, options, i; @@ -102,19 +103,23 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve //source $.extend( true, this, options ); - //Any functions that are passed as arguments are bound to the ready callback - /*jshint loopfunc:true*/ - for ( i = 0; i < arguments.length; i++ ) { - if ( $.isFunction( arguments[ i ] ) ) { - callback = arguments[ i ]; - this.addHandler( 'ready', function ( event ) { - callback( event ); - } ); - //only one callback per constructor - break; + if (!this.success) { + //Any functions that are passed as arguments are bound to the ready callback + for ( i = 0; i < arguments.length; i++ ) { + if ( $.isFunction( arguments[ i ] ) ) { + this.success = arguments[ i ]; + //only one callback per constructor + break; + } } } + if (this.success) { + this.addHandler( 'ready', function ( event ) { + _this.success( event ); + } ); + } + /** * Ratio of width to height * @member {Number} aspectRatio @@ -127,7 +132,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve */ /** * The size of the image tiles used to compose the image. - * Please note that tileSize may be deprecated in a future release. + * Please note that tileSize may be deprecated in a future release. * Instead the getTileSize(level) function should be used. * @member {Number} tileSize * @memberof OpenSeadragon.TileSource# @@ -148,12 +153,16 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve * @memberof OpenSeadragon.TileSource# */ /** - * + * * @member {Boolean} ready * @memberof OpenSeadragon.TileSource# */ if( 'string' == $.type( arguments[ 0 ] ) ){ + this.url = arguments[0]; + } + + if (this.url) { //in case the getImageInfo method is overriden and/or implies an //async mechanism set some safe defaults first this.aspectRatio = 1; @@ -165,7 +174,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve this.ready = false; //configuration via url implies the extending class //implements and 'configure' - this.getImageInfo( arguments[ 0 ] ); + this.getImageInfo( this.url ); } else { @@ -185,8 +194,8 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve Math.log( 2 ) ) : 0 ); - if( callback && $.isFunction( callback ) ){ - callback( this ); + if( this.success && $.isFunction( this.success ) ){ + this.success( this ); } } @@ -197,7 +206,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ /** - * Return the tileSize for a given level. + * Return the tileSize for a given level. * Subclasses should override this if tileSizes can be different at different levels * such as in IIIFTileSource. Code should use this function rather than reading * from .tileSize directly. tileSize may be deprecated in a future release. @@ -355,6 +364,10 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ } options = $TileSource.prototype.configure.apply( _this, [ data, url ]); + if (options.ajaxWithCredentials === undefined) { + options.ajaxWithCredentials = _this.ajaxWithCredentials; + } + readySource = new $TileSource( options ); _this.ready = true; /** @@ -383,45 +396,50 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ }); } else { // request info via xhr asynchronously. - $.makeAjaxRequest( url, function( xhr ) { - var data = processResponse( xhr ); - callback( data ); - }, function ( xhr, exc ) { - var msg; + $.makeAjaxRequest( { + url: url, + withCredentials: this.ajaxWithCredentials, + success: function( xhr ) { + var data = processResponse( xhr ); + callback( data ); + }, + error: function ( xhr, exc ) { + var msg; - /* - IE < 10 will block XHR requests to different origins. Any property access on the request - object will raise an exception which we'll attempt to handle by formatting the original - exception rather than the second one raised when we try to access xhr.status - */ - try { - msg = "HTTP " + xhr.status + " attempting to load TileSource"; - } catch ( e ) { - var formattedExc; - if ( typeof( exc ) == "undefined" || !exc.toString ) { - formattedExc = "Unknown error"; - } else { - formattedExc = exc.toString(); + /* + IE < 10 will block XHR requests to different origins. Any property access on the request + object will raise an exception which we'll attempt to handle by formatting the original + exception rather than the second one raised when we try to access xhr.status + */ + try { + msg = "HTTP " + xhr.status + " attempting to load TileSource"; + } catch ( e ) { + var formattedExc; + if ( typeof( exc ) == "undefined" || !exc.toString ) { + formattedExc = "Unknown error"; + } else { + formattedExc = exc.toString(); + } + + msg = formattedExc + " attempting to load TileSource"; } - msg = formattedExc + " attempting to load TileSource"; + /*** + * Raised when an error occurs loading a TileSource. + * + * @event open-failed + * @memberof OpenSeadragon.TileSource + * @type {object} + * @property {OpenSeadragon.TileSource} eventSource - A reference to the TileSource which raised the event. + * @property {String} message + * @property {String} source + * @property {?Object} userData - Arbitrary subscriber-defined object. + */ + _this.raiseEvent( 'open-failed', { + message: msg, + source: url + }); } - - /*** - * Raised when an error occurs loading a TileSource. - * - * @event open-failed - * @memberof OpenSeadragon.TileSource - * @type {object} - * @property {OpenSeadragon.TileSource} eventSource - A reference to the TileSource which raised the event. - * @property {String} message - * @property {String} source - * @property {?Object} userData - Arbitrary subscriber-defined object. - */ - _this.raiseEvent( 'open-failed', { - message: msg, - source: url - }); }); } diff --git a/src/viewer.js b/src/viewer.js index 781af981..5dcdd1cd 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -2051,14 +2051,22 @@ function getTileSourceImplementation( viewer, tileSource, successCallback, setTimeout( function() { if ( $.type( tileSource ) == 'string' ) { //If its still a string it means it must be a url at this point - tileSource = new $.TileSource( tileSource, function( event ) { - successCallback( event.tileSource ); + tileSource = new $.TileSource({ + url: tileSource, + ajaxWithCredentials: viewer.ajaxWithCredentials, + success: function( event ) { + successCallback( event.tileSource ); + } }); tileSource.addHandler( 'open-failed', function( event ) { failCallback( event ); } ); } else if ( $.isPlainObject( tileSource ) || tileSource.nodeType ) { + if (tileSource.ajaxWithCredentials === undefined) { + tileSource.ajaxWithCredentials = viewer.ajaxWithCredentials; + } + if ( $.isFunction( tileSource.getTileUrl ) ) { //Custom tile source var customTileSource = new $.TileSource( tileSource );