Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

New events: loaderror for Tile, tileerror for Layer.Grid. #283

Merged
merged 1 commit into from

2 participants

@ahocevar
Owner

With this event, users that previously used OpenLayers.Util.onImageLoadError now have an API way to handle tile loading errors with more than just a static background image.

The new events will also be useful for offline storage of tiles, to fall back from an online image to one from local storage.

@bartvde
Owner

This looks good, no remarks, please merge if you can confirm that relevant tests still pass in IE8, IE9, Chrome, Safari and Firefox. TIA.

@ahocevar ahocevar merged commit d6ffd60 into openlayers:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
20 lib/OpenLayers/Layer/Grid.js
@@ -202,6 +202,10 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* track of the loading progress. Listeners are called with an object
* with a tile property as first argument, making the loded tile
* available to the listener.
+ * tileerror - Triggered before the tileloaded event (i.e. when the tile is
+ * still hidden) if a tile failed to load. Listeners receive an object
+ * as first argument, which has a tile property that references the
+ * tile that could not be loaded.
*/
/**
@@ -969,7 +973,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
this.numLoadingTiles++;
};
- tile.events.register("loadstart", this, tile.onLoadStart);
tile.onLoadEnd = function() {
this.numLoadingTiles--;
@@ -987,8 +990,18 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
}
};
- tile.events.register("loadend", this, tile.onLoadEnd);
- tile.events.register("unload", this, tile.onLoadEnd);
+
+ tile.onLoadError = function() {
+ this.events.triggerEvent("tileerror", {tile: tile});
+ };
+
+ tile.events.on({
+ "loadstart": tile.onLoadStart,
+ "loadend": tile.onLoadEnd,
+ "unload": tile.onLoadEnd,
+ "loaderror": tile.onLoadError,
+ scope: this
+ });
},
/**
@@ -1005,6 +1018,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
"loadstart": tile.onLoadStart,
"loadend": tile.onLoadEnd,
"unload": tile.onLoadEnd,
+ "loaderror": tile.onLoadError,
scope: this
});
},
View
2  lib/OpenLayers/Tile.js
@@ -40,6 +40,8 @@ OpenLayers.Tile = OpenLayers.Class({
* to call <draw>(true) to actually draw the tile.
* loadstart - Triggered when tile loading starts.
* loadend - Triggered when tile loading ends.
+ * loaderror - Triggered before the loadend event (i.e. when the tile is
+ * still hidden) if the tile could not be loaded.
* reload - Triggered when an already loading tile is reloaded.
* unload - Triggered before a tile is unloaded.
*/
View
1  lib/OpenLayers/Tile/Image.js
@@ -425,6 +425,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
this.setImgSrc(this.layer.getURL(this.bounds));
} else {
OpenLayers.Element.addClass(img, "olImageLoadError");
+ this.events.triggerEvent("loaderror");
this.onImageLoad();
}
}
View
6 notes/2.12.md
@@ -133,6 +133,12 @@ The internal `OpenLayers.Layer.getURLasync` function now take a bound, a callbac
Vector editing across the date line works reliably now. To make this work, OpenLayers won't zoom out to resolutions where more than one world is visible any more. For maps that have base layers with wrapDateLine set to false, no zoom restrictions apply.
+## OpenLayers.Util.onImageLoadError no longer exists
+
+To replace a tile that couldn't be loaded with a static image, create a css selector for the `.olImageLoadError` class (e.g. a `background-image`).
+
+For more complex tile loading error handling, register a listener to the layer's `tileerror` event.
+
## Deprecated Components
A number of properties, methods, and constructors have been marked as deprecated for multiple releases in the 2.x series. For the 2.12 release this deprecated functionality has been moved to a separate deprecated.js file. If you use any of the constructors or methods below, you will have to explicitly include the deprecated.js file in your build (or add it in a separate `<script>` tag after OpenLayers.js).
View
14 tests/Layer/Grid.html
@@ -506,7 +506,7 @@
}
function test_Layer_Grid_addTileMonitoringHooks(t) {
- t.plan(15);
+ t.plan(17);
layer = new OpenLayers.Layer.Grid();
layer.events = {
@@ -519,6 +519,13 @@
events: {
register: function(name, obj, func) {
g_registered[name] = [obj, func];
+ },
+ on: function(obj) {
+ for (var o in obj) {
+ if (obj.hasOwnProperty(o)) {
+ tile.events.register(o, obj.scope, obj[o]);
+ }
+ }
}
}
}
@@ -551,6 +558,11 @@
entry = g_registered["loadend"];
t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, "loadend correctly registered");
+ g_events = [];
+ tile.onLoadError.apply(layer);
+ t.eq(g_events[0][0], "tileerror", "tileerror triggered");
+ t.ok(g_events[0][1].tile === tile, "tile passed as tile property to event object");
+
layer.numLoadingTiles = 2;
g_events = [];
tile.onLoadEnd.apply(layer);
View
19 tests/Tile/Image.html
@@ -375,7 +375,7 @@
// test for https://github.com/openlayers/openlayers/pull/36
// (more an integration test than a unit test)
function test_olImageLoadError(t) {
- t.plan(2);
+ t.plan(6);
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS("invalid", "", {layers: 'basic'});
@@ -386,10 +386,25 @@
var bounds = new OpenLayers.Bounds(1, 2, 3, 4);
var tile = new OpenLayers.Tile.Image(layer, position, bounds, null, size);
+ var log = [];
+ tile.events.register("loaderror", this, function(e) {
+ log.push([
+ e.object.imgDiv.style.visibility,
+ OpenLayers.Element.hasClass(e.object.imgDiv, 'olImageLoadError')
+ ]);
+ });
+ tile.events.register("loadend", this, function(e) {
+ log.push(e);
+ })
tile.draw();
t.delay_call(0.1, function() {
-
+
+ t.eq(log.length, 2, "loaderror and loadend events triggered");
+ t.eq(log[0][0], "hidden", "tile still hidden when loaderror is triggered");
+ t.eq(log[0][1], true, "tile has olImageLoadError class already when loaderror is triggered");
+ t.ok(log[1].object === tile, "loadend event triggered after loaderror");
+
// check initial state
t.ok(OpenLayers.Element.hasClass(tile.imgDiv, 'olImageLoadError'),
'tile image has the olImageLoadError class (init state)');
Something went wrong with that request. Please try again.