Addressing @elemoine's review comments.
Now the application no longer needs to care about the tile origin, because the CacheWrite control modifies the url if the CORS image loading is disabled and it is from a different origin. This only requires OpenLayers.ProxyHost to be properly configured. Also local storage keys use the original url instead of the proxied url, to make the CacheRead control work without proxy settings. No deferred exceptions are thrown any more. Instead, OpenLayers.Console is used to show an error message for security exceptions. We now check for OpenLayers.Tile.Image, because other tile types (e.g. UTFGrid) are not supported (yet). To make the same origin handling in the CacheWrite control easier, OpenLayers.Request now exposes the same origin logic from request.issue as a separate function, so it can also be used by other components.
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Control.js
|
||||
* @requires OpenLayers/Request.js
|
||||
* @requires OpenLayers/Console.js
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -84,12 +86,12 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
setMap: function(map) {
|
||||
OpenLayers.Control.prototype.setMap.apply(this, arguments);
|
||||
var i, layers = this.layers || this.map.layers;
|
||||
var i, layers = this.layers || map.layers;
|
||||
for (i=layers.length-1; i>=0; --i) {
|
||||
this.addLayer({layer: layers[i]});
|
||||
}
|
||||
if (!this.layers) {
|
||||
this.map.events.on({
|
||||
map.events.on({
|
||||
addlayer: this.addLayer,
|
||||
removeLayer: this.removeLayer,
|
||||
scope: this
|
||||
@@ -107,7 +109,11 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
||||
* <OpenLayers.Layer> instance
|
||||
*/
|
||||
addLayer: function(evt) {
|
||||
evt.layer.events.register("tileloaded", this, this.cache);
|
||||
evt.layer.events.on({
|
||||
tileloadstart: this.makeSameOrigin,
|
||||
tileloaded: this.cache,
|
||||
scope: this
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -120,7 +126,34 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
||||
* <OpenLayers.Layer> instance
|
||||
*/
|
||||
removeLayer: function(evt) {
|
||||
evt.layer.events.unregister("tileloaded", this, this.cache);
|
||||
evt.layer.events.un({
|
||||
tileloadstart: this.makeSameOrigin,
|
||||
tileloaded: this.cache,
|
||||
scope: this
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: makeSameOrigin
|
||||
* If the tile does not have CORS image loading enabled and is from a
|
||||
* different origin, use OpenLayers.ProxyHost to make it a same origin url.
|
||||
*
|
||||
* Parameters:
|
||||
* evt - {<OpenLayers.Event>}
|
||||
*/
|
||||
makeSameOrigin: function(evt) {
|
||||
if (this.active) {
|
||||
var tile = evt.tile;
|
||||
if (tile instanceof OpenLayers.Tile.Image &&
|
||||
!tile.crossOriginKeyword &&
|
||||
tile.url.substr(0, 5) !== "data:") {
|
||||
var sameOriginUrl = OpenLayers.Request.makeSameOrigin(
|
||||
tile.url, OpenLayers.ProxyHost
|
||||
);
|
||||
OpenLayers.Control.CacheWrite.urlMap[sameOriginUrl] = tile.url;
|
||||
tile.url = sameOriginUrl;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -135,14 +168,16 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
||||
cache: function(obj) {
|
||||
if (this.active && window.localStorage) {
|
||||
var tile = obj.tile;
|
||||
if (tile.url.substr(0, 5) !== 'data:') {
|
||||
if (tile instanceof OpenLayers.Tile.Image &&
|
||||
tile.url.substr(0, 5) !== 'data:') {
|
||||
try {
|
||||
var canvasContext = tile.getCanvasContext();
|
||||
if (canvasContext) {
|
||||
window.localStorage.setItem(
|
||||
"olCache_" + tile.url,
|
||||
"olCache_" + OpenLayers.Control.CacheWrite.urlMap[tile.url],
|
||||
canvasContext.canvas.toDataURL(this.imageFormat)
|
||||
);
|
||||
delete OpenLayers.Control.CacheWrite.urlMap[tile.url];
|
||||
}
|
||||
} catch(e) {
|
||||
// local storage full or CORS violation
|
||||
@@ -150,8 +185,7 @@ OpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {
|
||||
if (reason && this.quotaRegEx.test(reason)) {
|
||||
this.events.triggerEvent("cachefull", {tile: tile});
|
||||
} else {
|
||||
// throw exception in the next cycle
|
||||
window.setTimeout(function() { throw(e); }, 0);
|
||||
OpenLayers.Console.error(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -198,3 +232,12 @@ OpenLayers.Control.CacheWrite.clearCache = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Property: OpenLayers.Control.CacheWrite.urlMap
|
||||
* {Object} Mapping of same origin urls to cache url keys. Entries will be
|
||||
* deleted as soon as a tile was cached.
|
||||
*/
|
||||
OpenLayers.Control.CacheWrite.urlMap = {};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user