mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 14:46:10 +03:00
Fix docs, commit before upstream merge.
This commit is contained in:
parent
63f0adbc15
commit
360f0d6796
@ -48,7 +48,7 @@
|
||||
* @param {Boolean} [options.ajaxWithCredentials] - Whether to set withCredentials on AJAX requests.
|
||||
* @param {String} [options.crossOriginPolicy] - CORS policy to use for downloads
|
||||
* @param {String} [options.postData] - HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
||||
* see TileSource::getPostData) or null
|
||||
* see TileSource::getTilePostData) or null
|
||||
* @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.
|
||||
@ -193,7 +193,7 @@ $.ImageLoader.prototype = {
|
||||
* @param {String} [options.ajaxHeaders] - Headers to add to the image request if using AJAX.
|
||||
* @param {String|Boolean} [options.crossOriginPolicy] - CORS policy to use for downloads
|
||||
* @param {String} [options.postData] - POST parameters (usually but not necessarily in k=v&k2=v2... form,
|
||||
* see TileSource::getPostData) or null
|
||||
* see TileSource::getTilePostData) or null
|
||||
* @param {Boolean} [options.ajaxWithCredentials] - Whether to set withCredentials on AJAX
|
||||
* requests.
|
||||
* @param {Function} [options.callback] - Called once image has been downloaded.
|
||||
|
@ -2383,7 +2383,7 @@ function OpenSeadragon( options ){
|
||||
* @param {Object} options.headers - headers to add to the AJAX request
|
||||
* @param {String} options.responseType - the response type of the AJAX request
|
||||
* @param {String} options.postData - HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
||||
* see TileSource::getPostData), GET method used if null
|
||||
* see TileSource::getTilePostData), GET method used if null
|
||||
* @param {Boolean} [options.withCredentials=false] - whether to set the XHR's withCredentials
|
||||
* @throws {Error}
|
||||
* @returns {XMLHttpRequest}
|
||||
@ -2697,7 +2697,7 @@ function OpenSeadragon( options ){
|
||||
|
||||
//@private, runs tile update event
|
||||
invalidateTile: function(tile, image, tStamp, viewer, i = -1) {
|
||||
console.log(i, "tile: process", tile);
|
||||
//console.log(i, "tile: process", tile);
|
||||
|
||||
//todo consider also ability to cut execution of ongoing event if outdated by providing comparison timestamp
|
||||
viewer.raiseEventAwaiting('tile-needs-update', {
|
||||
|
104
src/tile.js
104
src/tile.js
@ -53,7 +53,7 @@
|
||||
* drawing operation, in pixels. Note that this only works when drawing with canvas; when drawing
|
||||
* with HTML the entire tile is always used.
|
||||
* @param {String} postData HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
||||
* see TileSource::getPostData) or null
|
||||
* see TileSource::getTilePostData) or null
|
||||
* @param {String} cacheKey key to act as a tile cache, must be unique for tiles with unique image data
|
||||
*/
|
||||
$.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, ajaxHeaders, sourceBounds, postData, cacheKey) {
|
||||
@ -112,7 +112,7 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, aja
|
||||
* Post parameters for this tile. For example, it can be an URL-encoded string
|
||||
* in k1=v1&k2=v2... format, or a JSON, or a FormData instance... or null if no POST request used
|
||||
* @member {String} postData HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
||||
* see TileSource::getPostData) or null
|
||||
* see TileSource::getTilePostData) or null
|
||||
* @memberof OpenSeadragon.Tile#
|
||||
*/
|
||||
this.postData = postData;
|
||||
@ -300,14 +300,15 @@ $.Tile.prototype = {
|
||||
return this._cKey;
|
||||
},
|
||||
set cacheKey(value) {
|
||||
if (this._cKey !== value) {
|
||||
let ref = this._caches[this._cKey];
|
||||
if (ref) {
|
||||
// make sure we free drawer internal cache
|
||||
ref.destroyInternalCache();
|
||||
}
|
||||
this._cKey = value;
|
||||
if (value === this.cacheKey) {
|
||||
return;
|
||||
}
|
||||
const cache = this.getCache(value);
|
||||
if (!cache) {
|
||||
// It's better to first set cache, then change the key to existing one. Warn if otherwise.
|
||||
$.console.warn("[Tile.cacheKey] should not be set manually. Use addCache() with setAsMain=true.");
|
||||
}
|
||||
this._updateMainCacheKey(value);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -431,11 +432,19 @@ $.Tile.prototype = {
|
||||
$.console.error("[Tile.cacheImageRecord] property has been deprecated. Use Tile::addCache.");
|
||||
const cache = this._caches[this.cacheKey];
|
||||
|
||||
if (!value) {
|
||||
if (cache) {
|
||||
this.removeCache(this.cacheKey);
|
||||
} else {
|
||||
const _this = this;
|
||||
cache.await().then(x => _this.addCache(this.cacheKey, x, cache.type, false));
|
||||
}
|
||||
|
||||
if (value) {
|
||||
// Note: the value's data is probably not preserved - if a cacheKey cache exists, it will ignore
|
||||
// data - it would have to call setData(...)
|
||||
// TODO: call setData() ?
|
||||
if (value.loaded) {
|
||||
this.addCache(this.cacheKey, value.data, value.type, true, false);
|
||||
} else {
|
||||
value.await().then(x => this.addCache(this.cacheKey, x, value.type, true, false));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -492,11 +501,8 @@ $.Tile.prototype = {
|
||||
|
||||
if (preserveOriginalData && this.cacheKey === this.originalCacheKey) {
|
||||
//caches equality means we have only one cache:
|
||||
// change current pointer to a new cache and create it: new tiles will
|
||||
// not arrive at this data, but at originalCacheKey state
|
||||
// todo setting cache key makes the notification trigger ensure we do not do unnecessary stuff
|
||||
this.cacheKey = "mod://" + this.originalCacheKey;
|
||||
return this.addCache(this.cacheKey, value, type)._promise;
|
||||
// create new cache record with main cache key changed to 'mod'
|
||||
return this.addCache("mod://" + this.originalCacheKey, value, type, true)._promise;
|
||||
}
|
||||
//else overwrite cache
|
||||
const cache = this.getCache(this.cacheKey);
|
||||
@ -512,7 +518,7 @@ $.Tile.prototype = {
|
||||
* @param {string} [key=this.cacheKey] cache key to read that belongs to this tile
|
||||
* @return {OpenSeadragon.CacheRecord}
|
||||
*/
|
||||
getCache: function(key = this.cacheKey) {
|
||||
getCache: function(key = this._cKey) {
|
||||
const cache = this._caches[key];
|
||||
if (cache) {
|
||||
cache.withTileReference(this);
|
||||
@ -526,20 +532,21 @@ $.Tile.prototype = {
|
||||
* value and extend it with some another unique content, by default overrides the existing
|
||||
* main cache used for drawing, if not existing.
|
||||
* @param {*} data data to cache - this data will be IGNORED if cache already exists!
|
||||
* @param {?string} type data type, will be guessed if not provided
|
||||
* @param {string} [type=undefined] data type, will be guessed if not provided
|
||||
* @param {boolean} [setAsMain=false] if true, the key will be set as the tile.cacheKey
|
||||
* @param [_safely=true] private
|
||||
* @returns {OpenSeadragon.CacheRecord|null} - The cache record the tile was attached to.
|
||||
*/
|
||||
addCache: function(key, data, type = undefined, _safely = true) {
|
||||
addCache: function(key, data, type = undefined, setAsMain = false, _safely = true) {
|
||||
if (!this.tiledImage) {
|
||||
return null; //async can access outside its lifetime
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
if (!this.tiledImage.__typeWarningReported) {
|
||||
if (!this.__typeWarningReported) {
|
||||
$.console.warn(this, "[Tile.addCache] called without type specification. " +
|
||||
"Automated deduction is potentially unsafe: prefer specification of data type explicitly.");
|
||||
this.tiledImage.__typeWarningReported = true;
|
||||
this.__typeWarningReported = true;
|
||||
}
|
||||
type = $.convertor.guessType(data);
|
||||
}
|
||||
@ -568,9 +575,31 @@ $.Tile.prototype = {
|
||||
}
|
||||
this._caches[key] = cachedItem;
|
||||
}
|
||||
|
||||
// Update cache key if differs and main requested
|
||||
if (!writesToRenderingCache && setAsMain) {
|
||||
this._updateMainCacheKey(key);
|
||||
}
|
||||
return cachedItem;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the main cache key for this tile and
|
||||
* performs necessary updates
|
||||
* @param value
|
||||
* @private
|
||||
*/
|
||||
_updateMainCacheKey: function(value) {
|
||||
let ref = this._caches[this._cKey];
|
||||
if (ref) {
|
||||
// make sure we free drawer internal cache
|
||||
ref.destroyInternalCache();
|
||||
}
|
||||
this._cKey = value;
|
||||
// when key changes the image probably needs re-render
|
||||
this.tiledImage.redraw();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the number of caches available to this tile
|
||||
* @returns {number} number of caches
|
||||
@ -585,11 +614,32 @@ $.Tile.prototype = {
|
||||
* @param {boolean} [freeIfUnused=true] set to false if zombie should be created
|
||||
*/
|
||||
removeCache: function(key, freeIfUnused = true) {
|
||||
if (this.cacheKey === key) {
|
||||
if (this.cacheKey !== this.originalCacheKey) {
|
||||
this.cacheKey = this.originalCacheKey;
|
||||
if (!this._caches[key]) {
|
||||
// try to erase anyway in case the cache got stuck in memory
|
||||
this.tiledImage._tileCache.unloadCacheForTile(this, key, freeIfUnused);
|
||||
return;
|
||||
}
|
||||
|
||||
const currentMainKey = this.cacheKey,
|
||||
originalDataKey = this.originalCacheKey,
|
||||
sameBuiltinKeys = currentMainKey === originalDataKey;
|
||||
|
||||
if (!sameBuiltinKeys && originalDataKey === key) {
|
||||
$.console.warn("[Tile.removeCache] original data must not be manually deleted: other parts of the code might rely on it!",
|
||||
"If you want the tile not to preserve the original data, toggle of data perseverance in tile.setData().");
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMainKey === key) {
|
||||
if (!sameBuiltinKeys && this._caches[originalDataKey]) {
|
||||
// if we have original data let's revert back
|
||||
// TODO consider calling drawer.getDataToDraw(...)
|
||||
// or even better, first ensure the data is compatible and then update...?
|
||||
this._updateMainCacheKey(originalDataKey);
|
||||
} else {
|
||||
$.console.warn("[Tile.removeCache] trying to remove the only cache that is used to draw the tile!");
|
||||
$.console.warn("[Tile.removeCache] trying to remove the only cache that can be used to draw the tile!",
|
||||
"If you want to remove the main cache, first set different cache as main with tile.addCache()");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (this.tiledImage._tileCache.unloadCacheForTile(this, key, freeIfUnused)) {
|
||||
|
@ -106,7 +106,7 @@
|
||||
*/
|
||||
setDataAs(data, type) {
|
||||
//allow set data with destroyed state, destroys the data if necessary
|
||||
$.console.assert(data !== undefined, "[CacheRecord.setDataAs] needs valid data to set!");
|
||||
$.console.assert(data !== undefined && data !== null, "[CacheRecord.setDataAs] needs valid data to set!");
|
||||
if (this._conversionJobQueue) {
|
||||
//delay saving if ongiong conversion, these were registered first
|
||||
let resolver = null;
|
||||
@ -412,7 +412,7 @@
|
||||
|
||||
_triggerNeedsDraw() {
|
||||
for (let tile of this._tiles) {
|
||||
tile.tiledImage._needsDraw = true;
|
||||
tile.tiledImage.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2095,14 +2095,9 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
* @param {?Boolean} [withEvent=true] do not trigger event if true
|
||||
*/
|
||||
_setTileLoaded: function(tile, data, cutoff, tileRequest, dataType, withEvent = true) {
|
||||
const originalDelete = tile.unload;
|
||||
tile.unload = (function () {
|
||||
throw `Cannot unload tile while being loaded!`;
|
||||
});
|
||||
|
||||
tile.tiledImage = this; //unloaded with tile.unload(), so we need to set it back
|
||||
// does nothing if tile.cacheKey already present
|
||||
tile.addCache(tile.cacheKey, data, dataType, false);
|
||||
tile.addCache(tile.cacheKey, data, dataType, false, false);
|
||||
|
||||
let resolver = null,
|
||||
increment = 0,
|
||||
@ -2135,13 +2130,11 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
||||
}
|
||||
return cacheRef;
|
||||
}).then(_ => {
|
||||
tile.unload = originalDelete;
|
||||
tile.loading = false;
|
||||
tile.loaded = true;
|
||||
resolver(tile);
|
||||
});
|
||||
} else {
|
||||
tile.unload = originalDelete;
|
||||
tile.loading = false;
|
||||
tile.loaded = true;
|
||||
resolver(tile);
|
||||
|
@ -55,7 +55,8 @@
|
||||
* @param {Object} options
|
||||
* You can either specify a URL, or literally define the TileSource (by specifying
|
||||
* width, height, tileSize, tileOverlap, minLevel, and maxLevel). For the former,
|
||||
* the extending class is expected to implement 'getImageInfo' and 'configure'.
|
||||
* the extending class is expected to implement 'supports' and 'configure'.
|
||||
* Note that _in this case, the child class of getImageInfo() is ignored!_
|
||||
* For the latter, the construction is assumed to occur through
|
||||
* the extending classes implementation of 'configure'.
|
||||
* @param {String} [options.url]
|
||||
@ -72,6 +73,7 @@
|
||||
* @param {Boolean} [options.splitHashDataForPost]
|
||||
* First occurrence of '#' in the options.url is used to split URL
|
||||
* and the latter part is treated as POST data (applies to getImageInfo(...))
|
||||
* Does not work if getImageInfo() is overridden and used (see the options description)
|
||||
* @param {Number} [options.width]
|
||||
* Width of the source image at max resolution in pixels.
|
||||
* @param {Number} [options.height]
|
||||
@ -176,6 +178,8 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
||||
* @memberof OpenSeadragon.TileSource#
|
||||
*/
|
||||
|
||||
// TODO potentially buggy behavior: what if .url is used by child class before it calls super constructor?
|
||||
// this can happen if old JS class definition is used
|
||||
if( 'string' === $.type( arguments[ 0 ] ) ){
|
||||
this.url = arguments[0];
|
||||
}
|
||||
@ -431,6 +435,12 @@ $.TileSource.prototype = {
|
||||
/**
|
||||
* Responsible for retrieving, and caching the
|
||||
* image metadata pertinent to this TileSources implementation.
|
||||
* There are three scenarios of opening a tile source:
|
||||
* 1) if it is a string parseable as XML or JSON, the string is converted to an object
|
||||
* 2) if it is a string, then
|
||||
* internally, this method
|
||||
* else
|
||||
*
|
||||
* @function
|
||||
* @param {String} url
|
||||
* @throws {Error}
|
||||
@ -560,7 +570,7 @@ $.TileSource.prototype = {
|
||||
* @property {String} message
|
||||
* @property {String} source
|
||||
* @property {String} postData - HTTP POST data (usually but not necessarily in k=v&k2=v2... form,
|
||||
* see TileSource::getPostData) or null
|
||||
* see TileSource::getTilePostData) or null
|
||||
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||
*/
|
||||
_this.raiseEvent( 'open-failed', {
|
||||
@ -777,7 +787,7 @@ $.TileSource.prototype = {
|
||||
* @param {Boolean} [context.ajaxWithCredentials] - Whether to set withCredentials on AJAX requests.
|
||||
* @param {String} [context.crossOriginPolicy] - CORS policy to use for downloads
|
||||
* @param {?String|?Object} [context.postData] - HTTP POST data (usually but not necessarily
|
||||
* in k=v&k2=v2... form, see TileSource::getPostData) or null
|
||||
* in k=v&k2=v2... form, see TileSource::getTilePostData) or null
|
||||
* @param {*} [context.userData] - Empty object to attach your own data and helper variables to.
|
||||
* @param {Function} [context.finish] - Should be called unless abort() was executed upon successful
|
||||
* data retrieval.
|
||||
|
@ -252,15 +252,15 @@
|
||||
|
||||
//load data
|
||||
const tile00 = createFakeTile('foo.jpg', fakeTiledImage0);
|
||||
tile00.addCache(tile00.cacheKey, 0, T_A, false);
|
||||
tile00.addCache(tile00.cacheKey, 0, T_A, false, false);
|
||||
const tile01 = createFakeTile('foo2.jpg', fakeTiledImage0);
|
||||
tile01.addCache(tile01.cacheKey, 0, T_B, false);
|
||||
tile01.addCache(tile01.cacheKey, 0, T_B, false, false);
|
||||
const tile10 = createFakeTile('foo3.jpg', fakeTiledImage1);
|
||||
tile10.addCache(tile10.cacheKey, 0, T_C, false);
|
||||
tile10.addCache(tile10.cacheKey, 0, T_C, false, false);
|
||||
const tile11 = createFakeTile('foo3.jpg', fakeTiledImage1);
|
||||
tile11.addCache(tile11.cacheKey, 0, T_C, false);
|
||||
tile11.addCache(tile11.cacheKey, 0, T_C, false, false);
|
||||
const tile12 = createFakeTile('foo.jpg', fakeTiledImage1);
|
||||
tile12.addCache(tile12.cacheKey, 0, T_A, false);
|
||||
tile12.addCache(tile12.cacheKey, 0, T_A, false, false);
|
||||
|
||||
const collideGetSet = async (tile, type) => {
|
||||
const value = await tile.getData(type, false);
|
||||
@ -446,15 +446,15 @@
|
||||
|
||||
//load data
|
||||
const tile00 = createFakeTile('foo.jpg', fakeTiledImage0);
|
||||
tile00.addCache(tile00.cacheKey, 0, T_A, false);
|
||||
tile00.addCache(tile00.cacheKey, 0, T_A, false, false);
|
||||
const tile01 = createFakeTile('foo2.jpg', fakeTiledImage0);
|
||||
tile01.addCache(tile01.cacheKey, 0, T_B, false);
|
||||
tile01.addCache(tile01.cacheKey, 0, T_B, false, false);
|
||||
const tile10 = createFakeTile('foo3.jpg', fakeTiledImage1);
|
||||
tile10.addCache(tile10.cacheKey, 0, T_C, false);
|
||||
tile10.addCache(tile10.cacheKey, 0, T_C, false, false);
|
||||
const tile11 = createFakeTile('foo3.jpg', fakeTiledImage1);
|
||||
tile11.addCache(tile11.cacheKey, 0, T_C, false);
|
||||
tile11.addCache(tile11.cacheKey, 0, T_C, false, false);
|
||||
const tile12 = createFakeTile('foo.jpg', fakeTiledImage1);
|
||||
tile12.addCache(tile12.cacheKey, 0, T_A, false);
|
||||
tile12.addCache(tile12.cacheKey, 0, T_A, false, false);
|
||||
|
||||
//test set/get data in async env
|
||||
(async function() {
|
||||
|
Loading…
Reference in New Issue
Block a user