From ef5e3890f6e8a54c8fb5ffa2e1c96f6a8f0234b6 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 27 Sep 2017 13:01:14 -0700 Subject: [PATCH] Ensure the map is updated after the sprite loads --- src/style/load_sprite.js | 7 +---- src/style/style.js | 21 ++++++++------ test/unit/style/style.test.js | 52 ++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 15 deletions(-) diff --git a/src/style/load_sprite.js b/src/style/load_sprite.js index 3976e70396f..473d836aee6 100644 --- a/src/style/load_sprite.js +++ b/src/style/load_sprite.js @@ -8,14 +8,9 @@ const {RGBAImage} = require('../util/image'); import type {StyleImage} from './style_image'; import type {RequestTransformFunction} from '../ui/map'; -module.exports = function(baseURL: ?string, +module.exports = function(baseURL: string, transformRequestCallback: RequestTransformFunction, callback: Callback<{[string]: StyleImage}>) { - if (!baseURL) { - callback(null, {}); - return; - } - let json: any, image, error; const format = browser.devicePixelRatio > 1 ? '@2x' : ''; diff --git a/src/style/style.js b/src/style/style.js index e52fe3cc2b6..197e4e04f23 100644 --- a/src/style/style.js +++ b/src/style/style.js @@ -192,17 +192,22 @@ class Style extends Evented { this.addSource(id, json.sources[id], {validate: false}); } - loadSprite(json.sprite, this.map._transformRequest, (err, images) => { - if (err) { - this.fire('error', err); - } else if (images) { - for (const id in images) { - this.imageManager.addImage(id, images[id]); + if (json.sprite) { + loadSprite(json.sprite, this.map._transformRequest, (err, images) => { + if (err) { + this.fire('error', err); + } else if (images) { + for (const id in images) { + this.imageManager.addImage(id, images[id]); + } } - } + this.imageManager.setLoaded(true); + this.fire('data', {dataType: 'style'}); + }); + } else { this.imageManager.setLoaded(true); - }); + } this.glyphManager.setURL(json.glyphs); diff --git a/test/unit/style/style.test.js b/test/unit/style/style.test.js index 9f4a4cd4dfd..b67c91e00e4 100644 --- a/test/unit/style/style.test.js +++ b/test/unit/style/style.test.js @@ -10,6 +10,8 @@ const util = require('../../../src/util/util'); const Evented = require('../../../src/util/evented'); const window = require('../../../src/util/window'); const rtlTextPlugin = require('../../../src/source/rtl_text_plugin'); +const ajax = require('../../../src/util/ajax'); +const browser = require('../../../src/util/browser'); function createStyleJSON(properties) { return util.extend({ @@ -170,7 +172,7 @@ test('Style#loadJSON', (t) => { callback(); }); - t.test('fires "dataloading"', (t) => { + t.test('fires "dataloading" (synchronously)', (t) => { const style = new Style(new StubMap()); const spy = t.spy(); @@ -183,6 +185,54 @@ test('Style#loadJSON', (t) => { t.end(); }); + t.test('fires "data" (asynchronously)', (t) => { + const style = new Style(new StubMap()); + + style.loadJSON(createStyleJSON()); + + style.on('data', (e) => { + t.equal(e.target, style); + t.equal(e.dataType, 'style'); + t.end(); + }); + }); + + t.test('fires "data" when the sprite finishes loading', (t) => { + window.useFakeXMLHttpRequest(); + window.server.respondWith('http://example.com/sprite.json', '{}'); + + // Stubbing rather than using a fake response because we need to bypass several Web APIs that + // aren't supported by jsdom: + // + // * `URL.createObjectURL` in ajax.getImage (https://github.com/tmpvar/jsdom/issues/1721) + // * `canvas.getContext('2d')` in browser.getImageData + // + t.stub(ajax, 'getImage').yields(null, new window.Image()); + t.stub(browser, 'getImageData'); + + const style = new Style(new StubMap()); + + style.loadJSON({ + "version": 8, + "sources": {}, + "layers": [], + "sprite": "http://example.com/sprite" + }); + + style.once('data', (e) => { + t.equal(e.target, style); + t.equal(e.dataType, 'style'); + + style.once('data', (e) => { + t.equal(e.target, style); + t.equal(e.dataType, 'style'); + t.end(); + }); + + window.server.respond(); + }); + }); + t.test('validates the style', (t) => { const style = new Style(new StubMap());