Merge pull request #9558 from tschaub/unlisten
Stop listening for image decoding
This commit is contained in:
+30
-22
@@ -58,9 +58,9 @@ class ImageWrapper extends ImageBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Array<import("./events.js").EventsKey>}
|
* @type {function():void}
|
||||||
*/
|
*/
|
||||||
this.imageListenerKeys_ = null;
|
this.unlisten_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
@@ -121,7 +121,7 @@ class ImageWrapper extends ImageBase {
|
|||||||
this.state = ImageState.LOADING;
|
this.state = ImageState.LOADING;
|
||||||
this.changed();
|
this.changed();
|
||||||
this.imageLoadFunction_(this, this.src_);
|
this.imageLoadFunction_(this, this.src_);
|
||||||
this.imageListenerKeys_ = listenImage(
|
this.unlisten_ = listenImage(
|
||||||
this.image_,
|
this.image_,
|
||||||
this.handleImageLoad_.bind(this),
|
this.handleImageLoad_.bind(this),
|
||||||
this.handleImageError_.bind(this)
|
this.handleImageError_.bind(this)
|
||||||
@@ -142,7 +142,10 @@ class ImageWrapper extends ImageBase {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
unlistenImage_() {
|
unlistenImage_() {
|
||||||
unlistenImage(this.imageListenerKeys_);
|
if (this.unlisten_) {
|
||||||
|
this.unlisten_();
|
||||||
|
this.unlisten_ = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,31 +153,36 @@ class ImageWrapper extends ImageBase {
|
|||||||
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element.
|
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element.
|
||||||
* @param {function():any} loadHandler Load callback function.
|
* @param {function():any} loadHandler Load callback function.
|
||||||
* @param {function():any} errorHandler Error callback function.
|
* @param {function():any} errorHandler Error callback function.
|
||||||
* @return {Array<import("./events.js").EventsKey>} listener keys.
|
* @return {function():void} Callback to stop listening.
|
||||||
*/
|
*/
|
||||||
export function listenImage(image, loadHandler, errorHandler) {
|
export function listenImage(image, loadHandler, errorHandler) {
|
||||||
const img = /** @type {HTMLImageElement} */ (image);
|
const img = /** @type {HTMLImageElement} */ (image);
|
||||||
if (img.decode) {
|
if (img.decode) {
|
||||||
img.decode().then(loadHandler).catch(errorHandler);
|
const promise = img.decode();
|
||||||
return null;
|
let listening = true;
|
||||||
} else {
|
const unlisten = function() {
|
||||||
const listenerKeys = [
|
listening = false;
|
||||||
listenOnce(img, EventType.LOAD, loadHandler),
|
};
|
||||||
listenOnce(img, EventType.ERROR, errorHandler)
|
promise.then(function() {
|
||||||
];
|
if (listening) {
|
||||||
return listenerKeys;
|
loadHandler();
|
||||||
|
}
|
||||||
|
}).catch(function(error) {
|
||||||
|
if (listening) {
|
||||||
|
errorHandler();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return unlisten;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
const listenerKeys = [
|
||||||
|
listenOnce(img, EventType.LOAD, loadHandler),
|
||||||
/**
|
listenOnce(img, EventType.ERROR, errorHandler)
|
||||||
* @param {Array<import("./events.js").EventsKey>} listenerKeys listener keys.
|
];
|
||||||
*/
|
return function unlisten() {
|
||||||
export function unlistenImage(listenerKeys) {
|
|
||||||
if (listenerKeys) {
|
|
||||||
listenerKeys.forEach(unlistenByKey);
|
listenerKeys.forEach(unlistenByKey);
|
||||||
listenerKeys = null;
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default ImageWrapper;
|
export default ImageWrapper;
|
||||||
|
|||||||
+8
-5
@@ -4,7 +4,7 @@
|
|||||||
import Tile from './Tile.js';
|
import Tile from './Tile.js';
|
||||||
import TileState from './TileState.js';
|
import TileState from './TileState.js';
|
||||||
import {createCanvasContext2D} from './dom.js';
|
import {createCanvasContext2D} from './dom.js';
|
||||||
import {listenImage, unlistenImage} from './Image.js';
|
import {listenImage} from './Image.js';
|
||||||
|
|
||||||
|
|
||||||
class ImageTile extends Tile {
|
class ImageTile extends Tile {
|
||||||
@@ -46,9 +46,9 @@ class ImageTile extends Tile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Array<import("./events.js").EventsKey>}
|
* @type {function():void}
|
||||||
*/
|
*/
|
||||||
this.imageListenerKeys_ = null;
|
this.unlisten_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -134,7 +134,7 @@ class ImageTile extends Tile {
|
|||||||
this.state = TileState.LOADING;
|
this.state = TileState.LOADING;
|
||||||
this.changed();
|
this.changed();
|
||||||
this.tileLoadFunction_(this, this.src_);
|
this.tileLoadFunction_(this, this.src_);
|
||||||
this.imageListenerKeys_ = listenImage(
|
this.unlisten_ = listenImage(
|
||||||
this.image_,
|
this.image_,
|
||||||
this.handleImageLoad_.bind(this),
|
this.handleImageLoad_.bind(this),
|
||||||
this.handleImageError_.bind(this)
|
this.handleImageError_.bind(this)
|
||||||
@@ -148,7 +148,10 @@ class ImageTile extends Tile {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
unlistenImage_() {
|
unlistenImage_() {
|
||||||
unlistenImage(this.imageListenerKeys_);
|
if (this.unlisten_) {
|
||||||
|
this.unlisten_();
|
||||||
|
this.unlisten_ = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import EventTarget from '../events/Target.js';
|
|||||||
import EventType from '../events/EventType.js';
|
import EventType from '../events/EventType.js';
|
||||||
import ImageState from '../ImageState.js';
|
import ImageState from '../ImageState.js';
|
||||||
import {shared as iconImageCache} from './IconImageCache.js';
|
import {shared as iconImageCache} from './IconImageCache.js';
|
||||||
import {listenImage, unlistenImage} from '../Image.js';
|
import {listenImage} from '../Image.js';
|
||||||
|
|
||||||
|
|
||||||
class IconImage extends EventTarget {
|
class IconImage extends EventTarget {
|
||||||
@@ -53,9 +53,9 @@ class IconImage extends EventTarget {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {Array<import("../events.js").EventsKey>}
|
* @type {function():void}
|
||||||
*/
|
*/
|
||||||
this.imageListenerKeys_ = null;
|
this.unlisten_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
@@ -191,7 +191,7 @@ class IconImage extends EventTarget {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleImageError_();
|
this.handleImageError_();
|
||||||
}
|
}
|
||||||
this.imageListenerKeys_ = listenImage(
|
this.unlisten_ = listenImage(
|
||||||
this.image_,
|
this.image_,
|
||||||
this.handleImageLoad_.bind(this),
|
this.handleImageLoad_.bind(this),
|
||||||
this.handleImageError_.bind(this)
|
this.handleImageError_.bind(this)
|
||||||
@@ -233,7 +233,10 @@ class IconImage extends EventTarget {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
unlistenImage_() {
|
unlistenImage_() {
|
||||||
unlistenImage(this.imageListenerKeys_);
|
if (this.unlisten_) {
|
||||||
|
this.unlisten_();
|
||||||
|
this.unlisten_ = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import {listenImage} from '../../../src/ol/Image.js';
|
||||||
|
|
||||||
|
|
||||||
|
describe('HTML Image loading', function() {
|
||||||
|
let handleLoad, handleError, img;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
handleLoad = sinon.spy();
|
||||||
|
handleError = sinon.spy();
|
||||||
|
img = new Image();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles load event', function(done) {
|
||||||
|
img.src = 'spec/ol/data/dot.png';
|
||||||
|
listenImage(img, handleLoad, handleError);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(handleLoad).to.be.called();
|
||||||
|
expect(handleError).not.to.be.called();
|
||||||
|
done();
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles error event', function(done) {
|
||||||
|
img.src = 'invalid.jpeg';
|
||||||
|
listenImage(img, handleLoad, handleError);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(handleLoad).not.to.be.called();
|
||||||
|
expect(handleError).to.be.called();
|
||||||
|
done();
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles cancelation', function(done) {
|
||||||
|
img.src = 'spec/ol/data/dot.png';
|
||||||
|
listenImage(img, handleLoad, handleError)();
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
expect(handleLoad).not.to.be.called();
|
||||||
|
expect(handleError).not.to.be.called();
|
||||||
|
done();
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user