From 7ac62fda0d79de7b3a3b17ee49652ad8b168025c Mon Sep 17 00:00:00 2001 From: David Manthey Date: Mon, 22 Jan 2018 10:48:57 -0500 Subject: [PATCH] Update jquery. This shouldn't result in any functional change. The main difference between jQuery 2.x and jQuery 3.x, at least as impacts GeoJS, is that `Deferred` objects are less synchronous. Specifically, the `done`, `fail`, and `always` methods can be synchronous if the deferred is resolved or rejected, but the `then` method is never synchronous. The major changes are in the tests which relied on the synchronicity for running the tests; they no longer do so, releasing time slices as appropriate. Since GeoJS `object`s could take native promises, there is code to use `always` if available and `then` if not. In other places, we rely on jQuery's `Deferred` having the `done` and `always` convenience functions. --- package-lock.json | 6 +- package.json | 2 +- src/fetchQueue.js | 4 +- src/imageTile.js | 4 +- src/object.js | 6 +- src/tile.js | 8 ++- src/transform.js | 2 +- tests/cases/fetchQueue.js | 103 +++++++++++++++++++------------ tests/cases/tile.js | 9 ++- tests/cases/tileLayer.js | 15 +++-- tests/cases/transform.js | 24 ++++--- tests/test-utils.js | 3 + tutorials/video_on_map/index.pug | 2 +- 13 files changed, 119 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index e32d93be34..72eece4d92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4315,9 +4315,9 @@ "dev": true }, "jquery": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", - "integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", + "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==", "dev": true }, "js-base64": { diff --git a/package.json b/package.json index f6c06f02fc..c9477b4059 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "istanbul-instrumenter-loader": "^0.2.0", "jaguarjs-jsdoc": "^1.0.2", "jasmine-core": "^2.4.1", - "jquery": "~2.2.1", + "jquery": "^3.3", "jsdoc": "^3.5", "jsdoc-autoprivate": "0.0.1", "json-loader": "^0.5.4", diff --git a/src/fetchQueue.js b/src/fetchQueue.js index f6f4ae92e9..ed26a5aeb2 100644 --- a/src/fetchQueue.js +++ b/src/fetchQueue.js @@ -96,9 +96,9 @@ module.exports = (function () { } var wait = $.Deferred(); var process = $.Deferred(); - wait.then(function () { + wait.done(function () { $.when(callback.call(defer)).always(process.resolve); - }, process.resolve); + }).fail(process.resolve); defer.__fetchQueue = wait; this._addToQueue(defer, atEnd); $.when(wait, process).always(function () { diff --git a/src/imageTile.js b/src/imageTile.js index 4461bd0669..5b3815a987 100644 --- a/src/imageTile.js +++ b/src/imageTile.js @@ -79,7 +79,7 @@ module.exports = (function () { this._image.src = this._url; // attach a promise interface to `this` - defer.then(function () { + defer.done(function () { this._fetched = true; }.bind(this)).promise(this); } @@ -96,7 +96,7 @@ module.exports = (function () { this.fadeIn = function (duration) { var promise = this.fetch(), defer = $.Deferred(); $(this._image).css('display', 'none'); - promise.then(function () { + promise.done(function () { $(this._image).fadeIn(duration, function () { defer.resolve(); }); diff --git a/src/object.js b/src/object.js index e958cd8657..e168e3f042 100644 --- a/src/object.js +++ b/src/object.js @@ -57,7 +57,11 @@ var object = function () { } } m_promiseCount += 1; - promise.then(onDone, onDone); + if (promise.always) { + promise.always(onDone); + } else { + promise.then(onDone, onDone); + } return m_this; }; diff --git a/src/tile.js b/src/tile.js index 14fee110c8..815b6eddbc 100644 --- a/src/tile.js +++ b/src/tile.js @@ -73,7 +73,7 @@ module.exports = (function () { */ this.fetch = function () { if (!this._fetched) { - $.get(this._url).then(function () { + $.get(this._url).done(function () { this._fetched = true; }.bind(this)).promise(this); } @@ -107,7 +107,11 @@ module.exports = (function () { this.fetch(); } // Call then on the new promise - this.then(onSuccess, onFailure); + if (this.done && this.fail) { + this.done(onSuccess).fail(onFailure); + } else { + this.then(onSuccess, onFailure); + } return this; }; diff --git a/src/transform.js b/src/transform.js index 4baf47eebe..160e507389 100644 --- a/src/transform.js +++ b/src/transform.js @@ -210,7 +210,7 @@ transform.lookup = function (projection) { return $.ajax({ url: 'http://epsg.io/?q=' + code + '&format=json' - }).then(function (data) { + }).done(function (data) { var result = (data.results || [])[0]; if (!result || !result.proj4) { return defer.reject(data).promise(); diff --git a/tests/cases/fetchQueue.js b/tests/cases/fetchQueue.js index 45deb5d452..bc92a371b7 100644 --- a/tests/cases/fetchQueue.js +++ b/tests/cases/fetchQueue.js @@ -13,9 +13,9 @@ describe('geo.core.fetchQueue', function () { reference += 1; item.process = function () { item.defer = $.Deferred(); - item.defer.then(function () { + item.defer.done(function () { report.push({ref: item.ref, success: true}); - }, function () { + }).fail(function () { report.push({ref: item.ref, success: false}); }).promise(item); return item; @@ -30,7 +30,7 @@ describe('geo.core.fetchQueue', function () { reference = 1; }); - it('queue is the exepected size', function () { + it('queue is the expected size', function (done) { var q = geo.fetchQueue({size: 2}), dlist = []; expect(q.length).toBe(0); @@ -70,15 +70,21 @@ describe('geo.core.fetchQueue', function () { expect(q.processing).toBe(2); dlist[0].defer.resolve(); - expect(q.length).toBe(0); - expect(q.processing).toBe(2); - - dlist[3].defer.resolve(); - expect(q.length).toBe(0); - expect(q.processing).toBe(1); + window.setTimeout(function () { // wait for next time slice + expect(q.length).toBe(0); + expect(q.processing).toBe(2); + + dlist[3].defer.resolve(); + window.setTimeout(function () { // wait for next time slice + expect(q.length).toBe(0); + expect(q.processing).toBe(1); + + done(); + }, 0); + }, 0); }); - it('queue size can be changed', function () { + it('queue size can be changed', function (done) { var q = geo.fetchQueue({size: 2}), dlist = []; expect(q.size).toBe(2); @@ -104,19 +110,26 @@ describe('geo.core.fetchQueue', function () { expect(q.processing).toBe(3); dlist[0].defer.resolve(); - expect(q.length).toBe(2); - expect(q.processing).toBe(2); - - dlist[1].defer.resolve(); - expect(q.length).toBe(2); - expect(q.processing).toBe(1); - - dlist[2].defer.resolve(); - expect(q.length).toBe(1); - expect(q.processing).toBe(1); + window.setTimeout(function () { // wait for next time slice + expect(q.length).toBe(2); + expect(q.processing).toBe(2); + + dlist[1].defer.resolve(); + window.setTimeout(function () { // wait for next time slice + expect(q.length).toBe(2); + expect(q.processing).toBe(1); + + dlist[2].defer.resolve(); + window.setTimeout(function () { // wait for next time slice + expect(q.length).toBe(1); + expect(q.processing).toBe(1); + done(); + }, 0); + }, 0); + }, 0); }); - it('queue removes and skips unneeded items', function () { + it('queue removes and skips unneeded items', function (done) { var q = geo.fetchQueue({ size: 2, track: 4, @@ -155,21 +168,28 @@ describe('geo.core.fetchQueue', function () { } } - while (q.processing) { - for (i = 0; i < dlist.length; i += 1) { - if (dlist[i].defer) { - dlist[i].defer.resolve(); + function process() { + if (q.processing) { + for (i = 0; i < dlist.length; i += 1) { + if (dlist[i].defer) { + dlist[i].defer.resolve(); + } } + window.setTimeout(process, 0); + return; } - } - expect(report.length).toBe(reportOrder.length); - for (i = 0; i < report.length; i += 1) { - expect(report[i].ref).toBe(reportOrder[i]); + expect(report.length).toBe(reportOrder.length); + for (i = 0; i < report.length; i += 1) { + expect(report[i].ref).toBe(reportOrder[i]); + } + done(); } + + process(); }); - it('batch ordering', function () { + it('batch ordering', function (done) { var q = geo.fetchQueue({size: 1}), dlist = [], i; var reportOrder = [ 1, 22, 23, 20, 19, 17, 13, 14, 16, 11, 10, 5, @@ -193,18 +213,25 @@ describe('geo.core.fetchQueue', function () { q.add(dlist[i], dlist[i].process, (i % 3) === 2); } - while (q.processing) { - for (i = 0; i < dlist.length; i += 1) { - if (dlist[i].defer) { - dlist[i].defer.resolve(); + function process() { + if (q.processing) { + for (i = 0; i < dlist.length; i += 1) { + if (dlist[i].defer) { + dlist[i].defer.resolve(); + } } + window.setTimeout(process, 0); + return; } - } - expect(report.length).toBe(reportOrder.length); - for (i = 0; i < report.length; i += 1) { - expect(report[i].ref).toBe(reportOrder[i]); + expect(report.length).toBe(reportOrder.length); + for (i = 0; i < report.length; i += 1) { + expect(report[i].ref).toBe(reportOrder[i]); + } + done(); } + + process(); }); }); }); diff --git a/tests/cases/tile.js b/tests/cases/tile.js index 38ef0d7d24..0a967c8618 100644 --- a/tests/cases/tile.js +++ b/tests/cases/tile.js @@ -147,7 +147,7 @@ describe('geo.tile', function () { }); }); - it('failure', function () { + it('failure', function (done) { // create a mocked sinon server instance that always responds with 404. var server = sinon.fakeServer.create(); @@ -165,8 +165,11 @@ describe('geo.tile', function () { }); server.respond(); - expect(called).toBe(true); - server.restore(); + window.setTimeout(function () { // wait for the next time slice + expect(called).toBe(true); + server.restore(); + done(); + }, 0); }); }); diff --git a/tests/cases/tileLayer.js b/tests/cases/tileLayer.js index 78de8b87aa..45f6bc7533 100644 --- a/tests/cases/tileLayer.js +++ b/tests/cases/tileLayer.js @@ -1471,7 +1471,7 @@ describe('geo.tileLayer', function () { expect(Object.keys(l.activeTiles).length).toBe(0); }); - it('invalid tile url', function () { + it('invalid tile url', function (done) { var server = sinon.fakeServer.create(); var spy = sinon.spy(); sinon.stub(console, 'warn', function () {}); @@ -1483,11 +1483,14 @@ describe('geo.tileLayer', function () { t.catch(spy); server.respond(); - expect(console.warn.calledOnce); - expect(spy.calledOnce).toBe(true); - expect(l.canvas().find('.geo-tile-container').length).toBe(0); - server.restore(); - console.warn.restore(); + window.setTimeout(function () { // wait for the next time slice + expect(console.warn.calledOnce); + expect(spy.calledOnce).toBe(true); + expect(l.canvas().find('.geo-tile-container').length).toBe(0); + server.restore(); + console.warn.restore(); + done(); + }, 0); }); it('cropped tile', function () { diff --git a/tests/cases/transform.js b/tests/cases/transform.js index 5f499b6a4e..f49138256e 100644 --- a/tests/cases/transform.js +++ b/tests/cases/transform.js @@ -119,7 +119,7 @@ describe('geo.transform', function () { expect(p.forward({x: 10, y: -10, z: 0})).toEqual({x: 10, y: -10, z: 0}); }); - it('lookup', function () { + it('lookup', function (done) { var spy = sinon.spy(), request; geo.transform.lookup('EPSG:5000').then(spy); @@ -147,16 +147,19 @@ describe('geo.transform', function () { }] })); - expect(spy.calledOnce).toBe(true); - expect(geo.transform.defs.hasOwnProperty('EPSG:5000')).toBe(true); + window.setTimeout(function () { // wait for the next time slice + expect(spy.calledOnce).toBe(true); + expect(geo.transform.defs.hasOwnProperty('EPSG:5000')).toBe(true); - geo.transform.lookup('EPSG:5000'); - expect(server.requests.length).toBe(1); + geo.transform.lookup('EPSG:5000'); + expect(server.requests.length).toBe(1); + done(); + }, 0); }); - it('invalid projection code', function () { + it('invalid projection code', function (done) { var spy = sinon.spy(), request; - geo.transform.lookup('EPSG:5001').fail(spy); + geo.transform.lookup('EPSG:5001').then(spy); request = server.requests[0]; request.respond(200, {'Content-Type': 'application/json'}, JSON.stringify({ @@ -165,8 +168,11 @@ describe('geo.transform', function () { results: [] })); - expect(spy.calledOnce).toBe(true); - expect(geo.transform.defs.hasOwnProperty('EPSG:5001')).toBe(false); + window.setTimeout(function () { // wait for the next time slice + expect(spy.calledOnce).toBe(true); + expect(geo.transform.defs.hasOwnProperty('EPSG:5001')).toBe(false); + done(); + }, 0); }); it('unknown projection type', function () { diff --git a/tests/test-utils.js b/tests/test-utils.js index c2702fb3ea..a6389d00fa 100644 --- a/tests/test-utils.js +++ b/tests/test-utils.js @@ -235,6 +235,9 @@ module.exports.mockDate = function (delta) { startDate += mockDelta; return new origDate(startDate); }; + geo.mockedDate.now = function () { + return startDate; + }; window.Date = geo.mockedDate; }; diff --git a/tutorials/video_on_map/index.pug b/tutorials/video_on_map/index.pug index 5308b35127..3e02ad1807 100644 --- a/tutorials/video_on_map/index.pug +++ b/tutorials/video_on_map/index.pug @@ -22,7 +22,7 @@ block mainTutorial :markdown-it The video requires a feature layer that supports video quads. - +codeblock('javascript', 2). + +codeblock('javascript', 2)(htmlvideo=true). var layer = map.createLayer('feature', { features: ['quad.video'] });