diff --git a/examples/cache-read.js b/examples/cache-read.js
index f8c42a9115..1f7988984e 100644
--- a/examples/cache-read.js
+++ b/examples/cache-read.js
@@ -1,5 +1,5 @@
var map, cacheRead;
-function init(){
+function init() {
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
@@ -8,15 +8,11 @@ function init(){
layers: "basic"
}, {
eventListeners: {
- tileloadstart: function(evt) {
- // send requests through proxy
- evt.tile.url = "proxy.cgi?url=" + encodeURIComponent(evt.tile.url);
- },
tileloaded: updateHits
}
})
],
- center: [0,0],
+ center: [0, 0],
zoom: 1
});
cacheRead = new OpenLayers.Control.CacheRead();
@@ -25,8 +21,8 @@ function init(){
// User interface
- var status = document.getElementById("status");
- var hits = 0;
+ var status = document.getElementById("status"),
+ hits = 0;
// update the number of cached tiles and detect local storage support
function updateHits(evt) {
diff --git a/examples/cache-write.html b/examples/cache-write.html
index e36f3de9b7..ca59f68d80 100644
--- a/examples/cache-write.html
+++ b/examples/cache-write.html
@@ -8,6 +8,7 @@
+
diff --git a/examples/cache-write.js b/examples/cache-write.js
index b47cb60134..8f4ec9e081 100644
--- a/examples/cache-write.js
+++ b/examples/cache-write.js
@@ -1,5 +1,9 @@
+// Use proxy to get same origin URLs for tiles that don't support CORS.
+OpenLayers.ProxyHost = "proxy.cgi?url=";
+
var map, cacheWrite;
-function init(){
+
+function init() {
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
@@ -8,15 +12,11 @@ function init(){
layers: "basic"
}, {
eventListeners: {
- tileloadstart: function(evt) {
- // send requests through proxy
- evt.tile.url = "proxy.cgi?url=" + encodeURIComponent(evt.tile.url);
- },
tileloaded: updateStatus
}
})
],
- center: [0,0],
+ center: [0, 0],
zoom: 1
});
cacheWrite = new OpenLayers.Control.CacheWrite({
diff --git a/examples/offline-storage.html b/examples/offline-storage.html
index 3cf235fdd4..1c510ca537 100644
--- a/examples/offline-storage.html
+++ b/examples/offline-storage.html
@@ -13,6 +13,7 @@
}
+
diff --git a/examples/offline-storage.js b/examples/offline-storage.js
index b82470159b..e0b5929791 100644
--- a/examples/offline-storage.js
+++ b/examples/offline-storage.js
@@ -1,5 +1,9 @@
+// Use proxy to get same origin URLs for tiles that don't support CORS.
+OpenLayers.ProxyHost = "proxy.cgi?url=";
+
var map, cacheWrite, cacheRead1, cacheRead2;
-function init(){
+
+function init() {
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
@@ -14,28 +18,13 @@ function init(){
layers: "basic"
}, {
eventListeners: {
- tileloadstart: function(evt) {
- // send requests through proxy
- evt.tile.url = "proxy.cgi?url=" + encodeURIComponent(evt.tile.url);
- },
tileloaded: updateStatus
}
})
],
- center: [0,0],
+ center: [0, 0],
zoom: 1
});
- cacheWrite = new OpenLayers.Control.CacheWrite({
- imageFormat: "image/jpeg",
- eventListeners: {
- cachefull: function() {
- if (seeding) {
- stopSeeding();
- }
- status.innerHTML = "Cache full.";
- }
- }
- });
// try cache before loading from remote resource
cacheRead1 = new OpenLayers.Control.CacheRead({
eventListeners: {
@@ -54,8 +43,19 @@ function init(){
}
}
});
+ cacheWrite = new OpenLayers.Control.CacheWrite({
+ imageFormat: "image/jpeg",
+ eventListeners: {
+ cachefull: function() {
+ if (seeding) {
+ stopSeeding();
+ }
+ status.innerHTML = "Cache full.";
+ }
+ }
+ });
var layerSwitcher = new OpenLayers.Control.LayerSwitcher();
- map.addControls([cacheWrite, cacheRead1, cacheRead2, layerSwitcher]);
+ map.addControls([cacheRead1, cacheRead2, cacheWrite, layerSwitcher]);
layerSwitcher.maximizeControl();
@@ -63,7 +63,6 @@ function init(){
// add UI and behavior
var status = document.getElementById("status"),
hits = document.getElementById("hits"),
- previousCount = -1,
cacheHits = 0,
seeding = false;
var read = document.getElementById("read");
@@ -107,7 +106,7 @@ function init(){
} else {
status.innerHTML = "Local storage not supported. Try a different browser.";
}
- if (evt.tile.url.substr(0, 5) === "data:") {
+ if (evt && evt.tile.url.substr(0, 5) === "data:") {
cacheHits++;
}
hits.innerHTML = cacheHits + " cache hits.";
diff --git a/lib/OpenLayers/Control/CacheRead.js b/lib/OpenLayers/Control/CacheRead.js
index 6f44c7bbab..2589fdf6ca 100644
--- a/lib/OpenLayers/Control/CacheRead.js
+++ b/lib/OpenLayers/Control/CacheRead.js
@@ -33,8 +33,8 @@ OpenLayers.Control.CacheRead = OpenLayers.Class(OpenLayers.Control, {
/**
* APIProperty: layers
- * {Array()}. Optional. If provided, only
- * these layers will receive tiles from the cache.
+ * {Array()}. Optional. If provided, only these
+ * layers will receive tiles from the cache.
*/
layers: null,
@@ -61,12 +61,12 @@ OpenLayers.Control.CacheRead = 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
@@ -109,9 +109,17 @@ OpenLayers.Control.CacheRead = OpenLayers.Class(OpenLayers.Control, {
* evt - {Object} Event object with a tile property.
*/
fetch: function(evt) {
- if (this.active && window.localStorage) {
+ if (this.active && window.localStorage &&
+ evt.tile instanceof OpenLayers.Tile.Image) {
var tile = evt.tile,
- dataURI = window.localStorage.getItem("olCache_" + tile.url);
+ url = tile.url;
+ // deal with modified tile urls when both CacheWrite and CacheRead
+ // are active
+ if (!tile.layer.crossOriginKeyword && OpenLayers.ProxyHost &&
+ url.indexOf(OpenLayers.ProxyHost) === 0) {
+ url = OpenLayers.Control.CacheWrite.urlMap[url];
+ }
+ var dataURI = window.localStorage.getItem("olCache_" + tile.url);
if (dataURI) {
tile.url = dataURI;
if (evt.type === "tileerror") {
diff --git a/lib/OpenLayers/Control/CacheWrite.js b/lib/OpenLayers/Control/CacheWrite.js
index 0311fde801..85ece0b1dd 100644
--- a/lib/OpenLayers/Control/CacheWrite.js
+++ b/lib/OpenLayers/Control/CacheWrite.js
@@ -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, {
* 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, {
* 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 - {}
+ */
+ 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 = {};
+
+
diff --git a/lib/OpenLayers/Request.js b/lib/OpenLayers/Request.js
index a5de46fdee..86e15d8099 100644
--- a/lib/OpenLayers/Request.js
+++ b/lib/OpenLayers/Request.js
@@ -65,6 +65,47 @@ OpenLayers.Request = {
*/
events: new OpenLayers.Events(this),
+ /**
+ * Method: makeSameOrigin
+ * Using the specified proxy, returns a same origin url of the provided url.
+ *
+ * Parameters:
+ * url - {String} An arbitrary url
+ * proxy {String|Function} The proxy to use to make the provided url a
+ * same origin url.
+ *
+ * Returns
+ * {String} the same origin url. If no proxy is provided, the returned url
+ * will be the same as the provided url.
+ */
+ makeSameOrigin: function(url, proxy) {
+ var sameOrigin = !(url.indexOf("http") == 0);
+ var urlParts = !sameOrigin && url.match(this.URL_SPLIT_REGEX);
+ if (urlParts) {
+ var location = window.location;
+ sameOrigin =
+ urlParts[1] == location.protocol &&
+ urlParts[3] == location.hostname;
+ var uPort = urlParts[4], lPort = location.port;
+ if (uPort != 80 && uPort != "" || lPort != "80" && lPort != "") {
+ sameOrigin = sameOrigin && uPort == lPort;
+ }
+ }
+ if (!sameOrigin) {
+ if (proxy) {
+ if (typeof proxy == "function") {
+ url = proxy(url);
+ } else {
+ url = proxy + encodeURIComponent(url);
+ }
+ } else {
+ OpenLayers.Console.warn(
+ OpenLayers.i18n("proxyNeeded"), {url: url});
+ }
+ }
+ return url;
+ },
+
/**
* APIMethod: issue
* Create a new XMLHttpRequest object, open it, set any headers, bind
@@ -153,30 +194,7 @@ OpenLayers.Request = {
var request = new OpenLayers.Request.XMLHttpRequest();
var url = OpenLayers.Util.urlAppend(config.url,
OpenLayers.Util.getParameterString(config.params || {}));
- var sameOrigin = !(url.indexOf("http") == 0);
- var urlParts = !sameOrigin && url.match(this.URL_SPLIT_REGEX);
- if (urlParts) {
- var location = window.location;
- sameOrigin =
- urlParts[1] == location.protocol &&
- urlParts[3] == location.hostname;
- var uPort = urlParts[4], lPort = location.port;
- if (uPort != 80 && uPort != "" || lPort != "80" && lPort != "") {
- sameOrigin = sameOrigin && uPort == lPort;
- }
- }
- if (!sameOrigin) {
- if (config.proxy) {
- if (typeof config.proxy == "function") {
- url = config.proxy(url);
- } else {
- url = config.proxy + encodeURIComponent(url);
- }
- } else {
- OpenLayers.Console.warn(
- OpenLayers.i18n("proxyNeeded"), {url: url});
- }
- }
+ url = OpenLayers.Request.makeSameOrigin(url, config.proxy);
request.open(
config.method, url, config.async, config.user, config.password
);