diff --git a/changelog.txt b/changelog.txt index 32b50acb..110d1905 100644 --- a/changelog.txt +++ b/changelog.txt @@ -37,6 +37,8 @@ OPENSEADRAGON CHANGELOG * You can now load tiles via AJAX and custom AJAX request headers (#1055) * Added fix for supporting weird filenames that look like JSONs (#1189) * Fixed: zoomTo/zoomBy ignore refPoint if immediately is true (#1184) +* Enabled configuration of ImageLoader timeout (#1192) +* Viewer.open() now supports an initialPage argument for sequenceMode (#1196) 2.2.1: diff --git a/src/imageloader.js b/src/imageloader.js index 4faaa1df..14eb576b 100644 --- a/src/imageloader.js +++ b/src/imageloader.js @@ -45,6 +45,7 @@ * @param {String} [options.crossOriginPolicy] - CORS policy to use for downloads * @param {Function} [options.callback] - Called once image has been downloaded. * @param {Function} [options.abort] - Called when this image job is aborted. + * @param {Number} [options.timeout] - The max number of milliseconds that this image job may take to complete. */ function ImageJob (options) { @@ -171,11 +172,13 @@ ImageJob.prototype = { * You generally won't have to interact with the ImageLoader directly. * @param {Object} options - Options for this ImageLoader. * @param {Number} [options.jobLimit] - The number of concurrent image requests. See imageLoaderLimit in {@link OpenSeadragon.Options} for details. + * @param {Number} [options.timeout] - The max number of milliseconds that an image job may take to complete. */ $.ImageLoader = function(options) { $.extend(true, this, { jobLimit: $.DEFAULT_SETTINGS.imageLoaderLimit, + timeout: $.DEFAULT_SETTINGS.timeout, jobQueue: [], jobsInProgress: 0 }, options); @@ -210,7 +213,8 @@ $.ImageLoader.prototype = { crossOriginPolicy: options.crossOriginPolicy, ajaxWithCredentials: options.ajaxWithCredentials, callback: complete, - abort: options.abort + abort: options.abort, + timeout: this.timeout }, newJob = new ImageJob(jobOptions); diff --git a/src/openseadragon.js b/src/openseadragon.js index dae45c68..8ed6adcb 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -411,6 +411,7 @@ * The max number of images we should keep in memory (per drawer). * * @property {Number} [timeout=30000] + * The max number of milliseconds that an image job may take to complete. * * @property {Boolean} [useCanvas=true] * Set to false to not use an HTML canvas element for image rendering even if canvas is supported. diff --git a/src/viewer.js b/src/viewer.js index 17120ae1..ded3ef4d 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -96,6 +96,12 @@ $.Viewer = function( options ) { //internal state and dom identifiers id: options.id, hash: options.hash || nextHash++, + /** + * Index for page to be shown first next time open() is called (only used in sequenceMode). + * @member {Number} initialPage + * @memberof OpenSeadragon.Viewer# + */ + initialPage: 0, //dom nodes /** @@ -370,7 +376,8 @@ $.Viewer = function( options ) { // Create the image loader this.imageLoader = new $.ImageLoader({ - jobLimit: this.imageLoaderLimit + jobLimit: this.imageLoaderLimit, + timeout: options.timeout }); // Create the tile cache @@ -481,11 +488,13 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, * except for the index property; images are added in sequence. * A TileSource specifier is anything you could pass as the tileSource property * of the options parameter for {@link OpenSeadragon.Viewer#addTiledImage}. + * @param {Number} initialPage - If sequenceMode is true, display this page initially + * for the given tileSources. If specified, will overwrite the Viewer's existing initialPage property. * @return {OpenSeadragon.Viewer} Chainable. * @fires OpenSeadragon.Viewer.event:open * @fires OpenSeadragon.Viewer.event:open-failed */ - open: function (tileSources) { + open: function (tileSources, initialPage) { var _this = this; this.close(); @@ -500,6 +509,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, this.referenceStrip = null; } + if (typeof initialPage != 'undefined' && !isNaN(initialPage)) { + this.initialPage = initialPage; + } + this.tileSources = tileSources; this._sequenceIndex = Math.max(0, Math.min(this.tileSources.length - 1, this.initialPage)); if (this.tileSources.length) { diff --git a/test/coverage.html b/test/coverage.html index 9262bb6e..7fda4329 100644 --- a/test/coverage.html +++ b/test/coverage.html @@ -81,6 +81,7 @@ + diff --git a/test/modules/imageloader.js b/test/modules/imageloader.js new file mode 100644 index 00000000..1750ea73 --- /dev/null +++ b/test/modules/imageloader.js @@ -0,0 +1,88 @@ +/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */ + +(function() { + var viewer, + baseOptions = { + id: 'example', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100 // Faster animation = faster tests + }; + + module('ImageLoader', { + setup: function () { + var example = $('
').appendTo("#qunit-fixture"); + + testLog.reset(); + }, + teardown: function () { + if (viewer && viewer.close) { + viewer.close(); + } + + viewer = null; + } + }); + + // ---------- + + test('Default timeout', function() { + var actual, + expected = OpenSeadragon.DEFAULT_SETTINGS.timeout, + message, + options = OpenSeadragon.extend(true, baseOptions, { + imageLoaderLimit: 1 + }), + viewer = OpenSeadragon(options), + imageLoader = viewer.imageLoader; + + message = 'ImageLoader timeout should be set to the default value of ' + expected + ' when none is specified'; + actual = imageLoader.timeout; + equal(actual, expected, message); + + // Manually seize the ImageLoader + imageLoader.jobsInProgress = imageLoader.jobLimit; + imageLoader.addJob({ + src: 'test', + loadWithAjax: false, + crossOriginPolicy: 'test', + ajaxWithCredentials: false, + abort: function() {} + }); + + message = 'ImageJob should inherit the ImageLoader timeout value'; + actual = imageLoader.jobQueue.shift().timeout; + equal(actual, expected, message); + }); + + // ---------- + + test('Configure timeout', function() { + var actual, + expected = 123456, + message, + options = OpenSeadragon.extend(true, baseOptions, { + imageLoaderLimit: 1, + timeout: expected + }), + viewer = OpenSeadragon(options), + imageLoader = viewer.imageLoader; + + message = 'ImageLoader timeout should be configurable'; + actual = imageLoader.timeout; + equal(actual, expected, message); + + imageLoader.jobsInProgress = imageLoader.jobLimit; + imageLoader.addJob({ + src: 'test', + loadWithAjax: false, + crossOriginPolicy: 'test', + ajaxWithCredentials: false, + abort: function() {} + }); + + message = 'ImageJob should inherit the ImageLoader timeout value'; + actual = imageLoader.jobQueue.shift().timeout; + equal(actual, expected, message); + }); + +})(); diff --git a/test/test.html b/test/test.html index b69247e8..16e7e54a 100644 --- a/test/test.html +++ b/test/test.html @@ -43,6 +43,7 @@ +