mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 22:56:11 +03:00
Fix comments on #2148: part 2. Better commens on the new TileSource API. Deprecation if 'tile-loaded' image event parameter. Unwrap ImageJob and add userData property.
This commit is contained in:
parent
45a7a4aaf3
commit
d82fd35323
@ -35,7 +35,6 @@
|
|||||||
(function($){
|
(function($){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
|
||||||
* @class ImageJob
|
* @class ImageJob
|
||||||
* @classdesc Handles downloading of a single image.
|
* @classdesc Handles downloading of a single image.
|
||||||
* @param {Object} options - Options for this ImageJob.
|
* @param {Object} options - Options for this ImageJob.
|
||||||
@ -50,7 +49,7 @@
|
|||||||
* @param {Function} [options.abort] - Called when this image job is aborted.
|
* @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.
|
* @param {Number} [options.timeout] - The max number of milliseconds that this image job may take to complete.
|
||||||
*/
|
*/
|
||||||
function ImageJob (options) {
|
$.ImageJob = function(options) {
|
||||||
|
|
||||||
$.extend(true, this, {
|
$.extend(true, this, {
|
||||||
timeout: $.DEFAULT_SETTINGS.timeout,
|
timeout: $.DEFAULT_SETTINGS.timeout,
|
||||||
@ -63,9 +62,16 @@ function ImageJob (options) {
|
|||||||
* @memberof OpenSeadragon.ImageJob#
|
* @memberof OpenSeadragon.ImageJob#
|
||||||
*/
|
*/
|
||||||
this.data = null;
|
this.data = null;
|
||||||
}
|
|
||||||
|
|
||||||
ImageJob.prototype = {
|
/**
|
||||||
|
* User workspace to populate with helper variables
|
||||||
|
* @member {*} user data, for people to append their data
|
||||||
|
* @memberof OpenSeadragon.ImageJob#
|
||||||
|
*/
|
||||||
|
this.userData = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ImageJob.prototype = {
|
||||||
errorMsg: null,
|
errorMsg: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,7 +106,6 @@ ImageJob.prototype = {
|
|||||||
|
|
||||||
this.callback(this);
|
this.callback(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +151,7 @@ $.ImageLoader.prototype = {
|
|||||||
if (!options.source) {
|
if (!options.source) {
|
||||||
$.console.error('ImageLoader.prototype.addJob() requires [options.source]. ' +
|
$.console.error('ImageLoader.prototype.addJob() requires [options.source]. ' +
|
||||||
'TileSource since new API defines how images are fetched. Creating a dummy TileSource.');
|
'TileSource since new API defines how images are fetched. Creating a dummy TileSource.');
|
||||||
let implementation = $.TileSource.prototype;
|
var implementation = $.TileSource.prototype;
|
||||||
options.source = {
|
options.source = {
|
||||||
downloadTileStart: implementation.downloadTileStart,
|
downloadTileStart: implementation.downloadTileStart,
|
||||||
downloadTileAbort: implementation.downloadTileAbort,
|
downloadTileAbort: implementation.downloadTileAbort,
|
||||||
@ -170,7 +175,7 @@ $.ImageLoader.prototype = {
|
|||||||
abort: options.abort,
|
abort: options.abort,
|
||||||
timeout: this.timeout
|
timeout: this.timeout
|
||||||
},
|
},
|
||||||
newJob = new ImageJob(jobOptions);
|
newJob = new $.ImageJob(jobOptions);
|
||||||
|
|
||||||
if ( !this.jobLimit || this.jobsInProgress < this.jobLimit ) {
|
if ( !this.jobLimit || this.jobsInProgress < this.jobLimit ) {
|
||||||
newJob.start();
|
newJob.start();
|
||||||
|
@ -298,7 +298,9 @@ $.Tile.prototype = {
|
|||||||
|
|
||||||
if ( !this.element ) {
|
if ( !this.element ) {
|
||||||
var image = this.image;
|
var image = this.image;
|
||||||
if (!this.image) return;
|
if (!this.image) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.element = $.makeNeutralElement( "div" );
|
this.element = $.makeNeutralElement( "div" );
|
||||||
this.imgElement = image.cloneNode();
|
this.imgElement = image.cloneNode();
|
||||||
@ -335,7 +337,7 @@ $.Tile.prototype = {
|
|||||||
* @return {Image}
|
* @return {Image}
|
||||||
*/
|
*/
|
||||||
get image() {
|
get image() {
|
||||||
this.cacheImageRecord.getImage();
|
return this.cacheImageRecord.getImage();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -367,8 +369,7 @@ $.Tile.prototype = {
|
|||||||
|
|
||||||
var position = this.position.times($.pixelDensityRatio),
|
var position = this.position.times($.pixelDensityRatio),
|
||||||
size = this.size.times($.pixelDensityRatio),
|
size = this.size.times($.pixelDensityRatio),
|
||||||
rendered,
|
rendered;
|
||||||
hasTransparency;
|
|
||||||
|
|
||||||
if (!this.context2D && !this.cacheImageRecord) {
|
if (!this.context2D && !this.cacheImageRecord) {
|
||||||
$.console.warn(
|
$.console.warn(
|
||||||
|
@ -139,8 +139,8 @@ $.TileCache.prototype = {
|
|||||||
if (!imageRecord) {
|
if (!imageRecord) {
|
||||||
|
|
||||||
if (!options.data) {
|
if (!options.data) {
|
||||||
$.console.error("[TileCache.cacheTile] options.image was renamed to options.data. '.image' attribute "
|
$.console.error("[TileCache.cacheTile] options.image was renamed to options.data. '.image' attribute " +
|
||||||
+ "has been deprecated and will be removed in the future.");
|
"has been deprecated and will be removed in the future.");
|
||||||
options.data = options.image;
|
options.data = options.image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1649,7 +1649,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
* @private
|
* @private
|
||||||
* @inner
|
* @inner
|
||||||
* @param {OpenSeadragon.Tile} tile
|
* @param {OpenSeadragon.Tile} tile
|
||||||
* @param {*} data image data
|
* @param {*} data image data, the output of TileSource.prototype.downloadTileFinish(), by default Image object
|
||||||
* @param {Number || undefined} cutoff
|
* @param {Number || undefined} cutoff
|
||||||
* @param {XMLHttpRequest || undefined} tileRequest
|
* @param {XMLHttpRequest || undefined} tileRequest
|
||||||
*/
|
*/
|
||||||
@ -1667,7 +1667,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
if (increment === 0) {
|
if (increment === 0) {
|
||||||
tile.loading = false;
|
tile.loading = false;
|
||||||
tile.loaded = true;
|
tile.loaded = true;
|
||||||
tile.hasTransparency = this.source.hasTransparency(
|
tile.hasTransparency = _this.source.hasTransparency(
|
||||||
tile.context2D, tile.url, tile.ajaxHeaders, tile.postData
|
tile.context2D, tile.url, tile.ajaxHeaders, tile.postData
|
||||||
);
|
);
|
||||||
if (!tile.context2D) {
|
if (!tile.context2D) {
|
||||||
@ -1689,8 +1689,9 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
* @event tile-loaded
|
* @event tile-loaded
|
||||||
* @memberof OpenSeadragon.Viewer
|
* @memberof OpenSeadragon.Viewer
|
||||||
* @type {object}
|
* @type {object}
|
||||||
* @property {Image|*} image - The image (data) of the tile.
|
* @property {Image || *} image - The image (data) of the tile. Deprecated.
|
||||||
* @property {*} data - image data
|
* @property {*} data - image data, the output of TileSource.prototype.downloadTileFinish(),
|
||||||
|
* by default Image object
|
||||||
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
|
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
|
||||||
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
|
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
|
||||||
* @property {XMLHttpRequest} tileRequest - The AJAX request that loaded this tile (if applicable).
|
* @property {XMLHttpRequest} tileRequest - The AJAX request that loaded this tile (if applicable).
|
||||||
@ -1704,7 +1705,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
tiledImage: this,
|
tiledImage: this,
|
||||||
tileRequest: tileRequest,
|
tileRequest: tileRequest,
|
||||||
get image() {
|
get image() {
|
||||||
$.console.error("[tile-loaded] event property 'image' has been deprecated and will be removed in the future");
|
$.console.error("[tile-loaded] event property 'image' has been deprecated and will be removed.");
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
data: data,
|
data: data,
|
||||||
|
@ -720,33 +720,38 @@ $.TileSource.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download tile data
|
* Download tile data.
|
||||||
* @param {object} context job context that you have to call finish(...) on. It also contains abort(...) function
|
* Note that if you override any of downloadTile*() functions, you should override all of them.
|
||||||
* that can be called to abort the job.
|
* @param {ImageJob} context job context that you have to call finish(...) on.
|
||||||
* @param {String} [context.src] - URL of image to download.
|
* @param {String} [context.src] - URL of image to download.
|
||||||
* @param {String} [context.loadWithAjax] - Whether to load this image with AJAX.
|
* @param {String} [context.loadWithAjax] - Whether to load this image with AJAX.
|
||||||
* @param {String} [context.ajaxHeaders] - Headers to add to the image request if using AJAX.
|
* @param {String} [context.ajaxHeaders] - Headers to add to the image request if using AJAX.
|
||||||
* @param {String} [context.crossOriginPolicy] - CORS policy to use for downloads
|
* @param {String} [context.crossOriginPolicy] - CORS policy to use for downloads
|
||||||
* @param {String} [context.postData] - HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
* @param {String} [context.postData] - HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
||||||
* see TileSrouce::getPostData) or null
|
* see TileSrouce::getPostData) or null
|
||||||
* @param {Function} [context.callback] - Called once image has been downloaded.
|
*
|
||||||
|
* @param {*} [context.userData] - Empty object to attach your own data and helper variables to.
|
||||||
|
* @param {Function} [context.callback] - Called automatically once image has been downloaded (triggered by finish).
|
||||||
|
* @param {Function} [context.finish] - Should be called unless abort() was executed, e.g. on all occasions,
|
||||||
|
* be it successful or unsuccessful request.
|
||||||
* @param {Function} [context.abort] - Called when this image job is aborted.
|
* @param {Function} [context.abort] - Called when this image job is aborted.
|
||||||
* @param {Number} [context.timeout] - The max number of milliseconds that this image job may take to complete.
|
* @param {Number} [context.timeout] - The max number of milliseconds that this image job may take to complete.
|
||||||
*/
|
*/
|
||||||
downloadTileStart: function (context) {
|
downloadTileStart: function (context) {
|
||||||
context.image = new Image();
|
var dataStore = context.userData;
|
||||||
|
dataStore.image = new Image();
|
||||||
|
|
||||||
context.image.onload = function(){
|
dataStore.image.onload = function(){
|
||||||
context.finish(true);
|
context.finish(true);
|
||||||
};
|
};
|
||||||
context.image.onabort = context.image.onerror = function() {
|
dataStore.image.onabort = dataStore.image.onerror = function() {
|
||||||
context.finish(false, "Image load aborted");
|
context.finish(false, "Image load aborted");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Load the tile with an AJAX request if the loadWithAjax option is
|
// Load the tile with an AJAX request if the loadWithAjax option is
|
||||||
// set. Otherwise load the image by setting the source proprety of the image object.
|
// set. Otherwise load the image by setting the source proprety of the image object.
|
||||||
if (context.loadWithAjax) {
|
if (context.loadWithAjax) {
|
||||||
context.request = $.makeAjaxRequest({
|
dataStore.request = $.makeAjaxRequest({
|
||||||
url: context.src,
|
url: context.src,
|
||||||
withCredentials: context.ajaxWithCredentials,
|
withCredentials: context.ajaxWithCredentials,
|
||||||
headers: context.ajaxHeaders,
|
headers: context.ajaxHeaders,
|
||||||
@ -778,7 +783,7 @@ $.TileSource.prototype = {
|
|||||||
} else {
|
} else {
|
||||||
// Create a URL for the blob data and make it the source of the image object.
|
// Create a URL for the blob data and make it the source of the image object.
|
||||||
// This will still trigger Image.onload to indicate a successful tile load.
|
// This will still trigger Image.onload to indicate a successful tile load.
|
||||||
context.image.src = (window.URL || window.webkitURL).createObjectURL(blb);
|
dataStore.image.src = (window.URL || window.webkitURL).createObjectURL(blb);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(request) {
|
error: function(request) {
|
||||||
@ -787,50 +792,59 @@ $.TileSource.prototype = {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (context.crossOriginPolicy !== false) {
|
if (context.crossOriginPolicy !== false) {
|
||||||
context.image.crossOrigin = context.crossOriginPolicy;
|
dataStore.image.crossOrigin = context.crossOriginPolicy;
|
||||||
}
|
}
|
||||||
|
dataStore.image.src = context.src;
|
||||||
context.image.src = context.src;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide means of aborting the execution.
|
* Provide means of aborting the execution.
|
||||||
* @param {object} context job, the same object as with downloadTileStart(..)
|
* Note that if you override any of downloadTile*() functions, you should override all of them.
|
||||||
|
* @param {ImageJob} context job, the same object as with downloadTileStart(..)
|
||||||
|
* @param {*} [context.userData] - Empty object to attach (and mainly read) your own data.
|
||||||
*/
|
*/
|
||||||
downloadTileAbort: function (context) {
|
downloadTileAbort: function (context) {
|
||||||
context.request.abort();
|
context.userData.request.abort();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} context job, the same object as with downloadTileStart(..)
|
* Note that if you override any of downloadTile*() functions, you should override all of them,
|
||||||
|
* unless you just want to for example here change the format of the data.
|
||||||
|
* Note that unless this function returns Image object, you should also override *TileCache() functions
|
||||||
|
* to re-define how the data is being cached.
|
||||||
|
* @param {ImageJob} context job, the same object as with downloadTileStart(..)
|
||||||
|
* @param {*} [context.userData] - Empty object to attach (and mainly read) your own data.
|
||||||
* @param successful true if successful
|
* @param successful true if successful
|
||||||
* @return {null|*} null to indicate missing data or data object
|
* @return {* || null} tile data in a format you want to have in the system, or null to indicate missing data
|
||||||
* for example, can return default value if the request was unsuccessful such as default error image
|
* also for example, a default value (white image? error image?) can be returned if the request was unsuccessful
|
||||||
*/
|
*/
|
||||||
downloadTileFinish: function (context, successful) {
|
downloadTileFinish: function (context, successful) {
|
||||||
if (!context.image) {
|
var image = context.userData.image;
|
||||||
|
if (!image) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
context.image.onload = context.image.onerror = context.image.onabort = null;
|
image.onload = image.onerror = image.onabort = null;
|
||||||
if (!successful) {
|
return successful ? image : null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return context.image;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create cache object from the result of the download process
|
* Create cache object from the result of the download process. The
|
||||||
* @param {Tile} tile instance the cache was created with
|
* cacheObject parameter should be used to attach the data to, there are no
|
||||||
|
* conventions on how it should be stored - all the logic is implemented within *TileCache() functions.
|
||||||
|
*
|
||||||
|
* Note that if you override any of *TileCache() functions, you should override all of them.
|
||||||
* @param {object} cacheObject context cache object
|
* @param {object} cacheObject context cache object
|
||||||
* @param {*} data the result of downloadTileFinish() function
|
* @param {*} data the result of downloadTileFinish() function
|
||||||
|
* @param {Tile} tile instance the cache was created with
|
||||||
*/
|
*/
|
||||||
createTileCache: function(cacheObject, data, tile) {
|
createTileCache: function(cacheObject, data, tile) {
|
||||||
cacheObject._data = data;
|
cacheObject._data = data;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache object destructor, unset all properties to allow GC collection.
|
* Cache object destructor, unset all properties you created to allow GC collection.
|
||||||
|
* Note that if you override any of *TileCache() functions, you should override all of them.
|
||||||
* @param {object} cacheObject context cache object
|
* @param {object} cacheObject context cache object
|
||||||
*/
|
*/
|
||||||
destroyTileCache: function (cacheObject) {
|
destroyTileCache: function (cacheObject) {
|
||||||
@ -840,6 +854,7 @@ $.TileSource.prototype = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Raw data getter
|
* Raw data getter
|
||||||
|
* Note that if you override any of *TileCache() functions, you should override all of them.
|
||||||
* @param {object} cacheObject context cache object
|
* @param {object} cacheObject context cache object
|
||||||
* @return {*} cache data
|
* @return {*} cache data
|
||||||
*/
|
*/
|
||||||
@ -851,6 +866,7 @@ $.TileSource.prototype = {
|
|||||||
* Compatibility image element getter
|
* Compatibility image element getter
|
||||||
* - plugins might need image representation of the data
|
* - plugins might need image representation of the data
|
||||||
* - div HTML rendering relies on image element presence
|
* - div HTML rendering relies on image element presence
|
||||||
|
* Note that if you override any of *TileCache() functions, you should override all of them.
|
||||||
* @param {object} cacheObject context cache object
|
* @param {object} cacheObject context cache object
|
||||||
* @return {Image} cache data as an Image
|
* @return {Image} cache data as an Image
|
||||||
*/
|
*/
|
||||||
@ -862,6 +878,7 @@ $.TileSource.prototype = {
|
|||||||
* Compatibility context 2D getter
|
* Compatibility context 2D getter
|
||||||
* - most heavily used rendering method is a canvas-based approach,
|
* - most heavily used rendering method is a canvas-based approach,
|
||||||
* convert the data to a canvas and return it's 2D context
|
* convert the data to a canvas and return it's 2D context
|
||||||
|
* Note that if you override any of *TileCache() functions, you should override all of them.
|
||||||
* @param {object} cacheObject context cache object
|
* @param {object} cacheObject context cache object
|
||||||
* @return {CanvasRenderingContext2D} context of the canvas representation of the cache data
|
* @return {CanvasRenderingContext2D} context of the canvas representation of the cache data
|
||||||
*/
|
*/
|
||||||
|
@ -2,35 +2,6 @@
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var tileSourceCacheAPI = {
|
|
||||||
createTileCache: function(cacheObject, data, tile) {
|
|
||||||
cacheObject._data = data;
|
|
||||||
},
|
|
||||||
destroyTileCache: function (cacheObject) {
|
|
||||||
cacheObject._data = null;
|
|
||||||
cacheObject._renderedContext = null;
|
|
||||||
},
|
|
||||||
getTileCacheData: function(cacheObject) {
|
|
||||||
return cacheObject._data;
|
|
||||||
},
|
|
||||||
getTileCacheDataAsImage: function(cacheObject) {
|
|
||||||
return cacheObject._data; //the data itself by default is Image
|
|
||||||
},
|
|
||||||
getTileCacheDataAsContext2D: function(cacheObject) {
|
|
||||||
if (!cacheObject._renderedContext) {
|
|
||||||
var canvas = document.createElement( 'canvas' );
|
|
||||||
canvas.width = cacheObject._data.width;
|
|
||||||
canvas.height = cacheObject._data.height;
|
|
||||||
cacheObject._renderedContext = canvas.getContext('2d');
|
|
||||||
cacheObject._renderedContext.drawImage( cacheObject._data, 0, 0 );
|
|
||||||
//since we are caching the prerendered image on a canvas
|
|
||||||
//allow the image to not be held in memory
|
|
||||||
cacheObject._data = null;
|
|
||||||
}
|
|
||||||
return cacheObject._renderedContext;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
QUnit.module('TileCache', {
|
QUnit.module('TileCache', {
|
||||||
beforeEach: function () {
|
beforeEach: function () {
|
||||||
@ -49,11 +20,11 @@
|
|||||||
};
|
};
|
||||||
var fakeTiledImage0 = {
|
var fakeTiledImage0 = {
|
||||||
viewer: fakeViewer,
|
viewer: fakeViewer,
|
||||||
source: tileSourceCacheAPI
|
source: OpenSeadragon.TileSource.prototype
|
||||||
};
|
};
|
||||||
var fakeTiledImage1 = {
|
var fakeTiledImage1 = {
|
||||||
viewer: fakeViewer,
|
viewer: fakeViewer,
|
||||||
source: tileSourceCacheAPI
|
source: OpenSeadragon.TileSource.prototype
|
||||||
};
|
};
|
||||||
|
|
||||||
var fakeTile0 = {
|
var fakeTile0 = {
|
||||||
@ -106,7 +77,7 @@
|
|||||||
};
|
};
|
||||||
var fakeTiledImage0 = {
|
var fakeTiledImage0 = {
|
||||||
viewer: fakeViewer,
|
viewer: fakeViewer,
|
||||||
source: tileSourceCacheAPI
|
source: OpenSeadragon.TileSource.prototype
|
||||||
};
|
};
|
||||||
|
|
||||||
var fakeTile0 = {
|
var fakeTile0 = {
|
||||||
|
Loading…
Reference in New Issue
Block a user