Do not cache data from aborted tile loads
This also results in a simplified cache method that can more easily be overridden for use with other storage providers.
This commit is contained in:
@@ -111,7 +111,7 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
addLayer: function(evt) {
|
addLayer: function(evt) {
|
||||||
evt.layer.events.on({
|
evt.layer.events.on({
|
||||||
tileloadstart: this.makeSameOrigin,
|
tileloadstart: this.makeSameOrigin,
|
||||||
tileloaded: this.cache,
|
tileloaded: this.onTileloaded,
|
||||||
scope: this
|
scope: this
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -128,7 +128,7 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
removeLayer: function(evt) {
|
removeLayer: function(evt) {
|
||||||
evt.layer.events.un({
|
evt.layer.events.un({
|
||||||
tileloadstart: this.makeSameOrigin,
|
tileloadstart: this.makeSameOrigin,
|
||||||
tileloaded: this.cache,
|
tileloaded: this.onTileloaded,
|
||||||
scope: this
|
scope: this
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -156,6 +156,22 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: onTileloaded
|
||||||
|
* Decides whether a tile can be cached and calls the cache method.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* evt - {Event}
|
||||||
|
*/
|
||||||
|
onTileloaded: function(evt) {
|
||||||
|
if (this.active && !evt.aborted &&
|
||||||
|
evt.tile instanceof OpenLayers.Tile.Image &&
|
||||||
|
evt.tile.url.substr(0, 5) !== 'data:') {
|
||||||
|
this.cache({tile: evt.tile});
|
||||||
|
delete OpenLayers.Control.CacheWrite.urlMap[evt.tile.url];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: cache
|
* Method: cache
|
||||||
* Adds a tile to the cache. When the cache is full, the "cachefull" event
|
* Adds a tile to the cache. When the cache is full, the "cachefull" event
|
||||||
@@ -166,29 +182,25 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
|||||||
* <OpenLayers.Tile.Image> with the data to add to the cache
|
* <OpenLayers.Tile.Image> with the data to add to the cache
|
||||||
*/
|
*/
|
||||||
cache: function(obj) {
|
cache: function(obj) {
|
||||||
if (this.active && window.localStorage) {
|
if (window.localStorage) {
|
||||||
var tile = obj.tile;
|
var tile = obj.tile;
|
||||||
if (tile instanceof OpenLayers.Tile.Image &&
|
try {
|
||||||
tile.url.substr(0, 5) !== 'data:') {
|
var canvasContext = tile.getCanvasContext();
|
||||||
try {
|
if (canvasContext) {
|
||||||
var canvasContext = tile.getCanvasContext();
|
var urlMap = OpenLayers.Control.CacheWrite.urlMap;
|
||||||
if (canvasContext) {
|
var url = urlMap[tile.url] || tile.url;
|
||||||
var urlMap = OpenLayers.Control.CacheWrite.urlMap;
|
window.localStorage.setItem(
|
||||||
var url = urlMap[tile.url] || tile.url;
|
"olCache_" + url,
|
||||||
window.localStorage.setItem(
|
canvasContext.canvas.toDataURL(this.imageFormat)
|
||||||
"olCache_" + url,
|
);
|
||||||
canvasContext.canvas.toDataURL(this.imageFormat)
|
}
|
||||||
);
|
} catch(e) {
|
||||||
delete urlMap[tile.url];
|
// local storage full or CORS violation
|
||||||
}
|
var reason = e.name || e.message;
|
||||||
} catch(e) {
|
if (reason && this.quotaRegEx.test(reason)) {
|
||||||
// local storage full or CORS violation
|
this.events.triggerEvent("cachefull", {tile: tile});
|
||||||
var reason = e.name || e.message;
|
} else {
|
||||||
if (reason && this.quotaRegEx.test(reason)) {
|
OpenLayers.Console.error(e.toString());
|
||||||
this.events.triggerEvent("cachefull", {tile: tile});
|
|
||||||
} else {
|
|
||||||
OpenLayers.Console.error(e.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,8 +262,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
* loaded, as a means of progress update to listeners.
|
* loaded, as a means of progress update to listeners.
|
||||||
* listeners can access 'numLoadingTiles' if they wish to keep
|
* listeners can access 'numLoadingTiles' if they wish to keep
|
||||||
* track of the loading progress. Listeners are called with an object
|
* track of the loading progress. Listeners are called with an object
|
||||||
* with a tile property as first argument, making the loded tile
|
* with a 'tile' property as first argument, making the loded tile
|
||||||
* available to the listener.
|
* available to the listener, and an 'aborted' property, which will be
|
||||||
|
* true when loading was aborted and no tile data is available.
|
||||||
* tileerror - Triggered before the tileloaded event (i.e. when the tile is
|
* tileerror - Triggered before the tileloaded event (i.e. when the tile is
|
||||||
* still hidden) if a tile failed to load. Listeners receive an object
|
* still hidden) if a tile failed to load. Listeners receive an object
|
||||||
* as first argument, which has a tile property that references the
|
* as first argument, which has a tile property that references the
|
||||||
@@ -1090,9 +1091,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
this.numLoadingTiles++;
|
this.numLoadingTiles++;
|
||||||
};
|
};
|
||||||
|
|
||||||
tile.onLoadEnd = function() {
|
tile.onLoadEnd = function(evt) {
|
||||||
this.numLoadingTiles--;
|
this.numLoadingTiles--;
|
||||||
this.events.triggerEvent("tileloaded", {tile: tile});
|
this.events.triggerEvent("tileloaded", {
|
||||||
|
tile: tile,
|
||||||
|
aborted: evt.type === "unload"
|
||||||
|
});
|
||||||
//if that was the last tile, then trigger a 'loadend' on the layer
|
//if that was the last tile, then trigger a 'loadend' on the layer
|
||||||
if (this.tileQueue.length === 0 && this.numLoadingTiles === 0) {
|
if (this.tileQueue.length === 0 && this.numLoadingTiles === 0) {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t.plan(3);
|
t.plan(4);
|
||||||
OpenLayers.Control.CacheWrite.clearCache();
|
OpenLayers.Control.CacheWrite.clearCache();
|
||||||
var length = window.localStorage.length;
|
var length = window.localStorage.length;
|
||||||
|
|
||||||
@@ -69,6 +69,9 @@
|
|||||||
var content = canvasContext ? canvasContext.canvas.toDataURL("image/png") : null;
|
var content = canvasContext ? canvasContext.canvas.toDataURL("image/png") : null;
|
||||||
t.eq(window.localStorage.getItem("olCache_"+url), content, "localStorage contains correct image data");
|
t.eq(window.localStorage.getItem("olCache_"+url), content, "localStorage contains correct image data");
|
||||||
|
|
||||||
|
layer.events.triggerEvent('tileloaded', {aborted: true, tile: layer.grid[1][1]});
|
||||||
|
t.eq(window.localStorage.length, length + (canvasContext ? tiles-1 : 0), "tile aborted during load not cached");
|
||||||
|
|
||||||
var key = Math.random();
|
var key = Math.random();
|
||||||
window.localStorage.setItem(key, "bar");
|
window.localStorage.setItem(key, "bar");
|
||||||
OpenLayers.Control.CacheWrite.clearCache();
|
OpenLayers.Control.CacheWrite.clearCache();
|
||||||
|
|||||||
Reference in New Issue
Block a user