From b7081a2f6e4948a963368cbce7aedb826793bbb3 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Fri, 21 Sep 2018 10:30:47 -0700 Subject: [PATCH] Replace deferreds with Promise in PJSCodeInjector and PJSResourceCache (#680) --- build/js/live-editor.output_pjs.js | 203 ++++++++++++++-------------- js/output/pjs/pjs-code-injector.js | 119 ++++++++-------- js/output/pjs/pjs-resource-cache.js | 84 ++++++------ 3 files changed, 200 insertions(+), 206 deletions(-) diff --git a/build/js/live-editor.output_pjs.js b/build/js/live-editor.output_pjs.js index 8c8e4f3fe..e36079601 100644 --- a/build/js/live-editor.output_pjs.js +++ b/build/js/live-editor.output_pjs.js @@ -376,38 +376,37 @@ var PJSCodeInjector = (function () { * * @param {string} userCode: code to lint * @param {boolean} skip: skips linting if true and resolves Deferred immediately - * @returns {$.Deferred} resolves an array of lint errors + * @returns {Promise} resolves an array of lint errors */ value: function lint(userCode, skip) { var _this3 = this; - var deferred = $.Deferred(); - if (skip || !userCode) { - deferred.resolve([]); - return deferred; - } + return new Promise(function (resolve) { + if (skip || !userCode) { + resolve([]); + return; + } - // Build a string of options to feed into JSHint - // All properties are defined in the config - var hintCode = "/*jshint " + this.propListString(this.JSHint) + " */" + ( + // Build a string of options to feed into JSHint + // All properties are defined in the config + var hintCode = "/*jshint " + _this3.propListString(_this3.JSHint) + " */" + ( - // Build a string of variables names to feed into JSHint - // This lets JSHint know which variables are globally exposed - // and which can be overridden, more details: - // http://www.jshint.com/about/ - // propName: true (is a global property, but can be overridden) - // propName: false (is a global property, cannot be overridden) - "/*global " + this.propListString(this.props) + " */\n") + + // Build a string of variables names to feed into JSHint + // This lets JSHint know which variables are globally exposed + // and which can be overridden, more details: + // http://www.jshint.com/about/ + // propName: true (is a global property, but can be overridden) + // propName: false (is a global property, cannot be overridden) + "/*global " + _this3.propListString(_this3.props) + " */\n") + - // The user's code to execute - userCode; + // The user's code to execute + userCode; - this.hintWorker.exec(hintCode, function (hintData, hintErrors) { - _this3.globals = _this3.extractGlobals(hintData); - deferred.resolve(hintErrors); + _this3.hintWorker.exec(hintCode, function (hintData, hintErrors) { + _this3.globals = _this3.extractGlobals(hintData); + resolve(hintErrors); + }); }); - - return deferred; } }, { key: "extractGlobals", @@ -455,9 +454,9 @@ var PJSCodeInjector = (function () { // Make sure the object actually exists before we try // to inject stuff into it if (!this.processing[name]) { - if ($.isArray(obj)) { + if (Array.isArray(obj)) { this.processing[name] = []; - } else if ($.isFunction(obj)) { + } else if (typeof obj === "function") { this.processing[name] = function () {}; } else { this.processing[name] = {}; @@ -1106,46 +1105,44 @@ var PJSCodeInjector = (function () { document.body.appendChild(imageHolder); var loadImage = function loadImage(filename) { - var deferred = $.Deferred(); - var img = document.createElement("img"); - img.onload = (function () { + return new Promise(function (resolve) { + var img = document.createElement("img"); + img.onload = function () { + resourceCache[filename] = img; + resolve(); + }; + img.onerror = function () { + resolve(); // always resolve + }; + + img.src = imageDir + filename; + imageHolder.appendChild(img); resourceCache[filename] = img; - deferred.resolve(); - }).bind(this); - img.onerror = (function () { - deferred.resolve(); // always resolve - }).bind(this); - - img.src = imageDir + filename; - imageHolder.appendChild(img); - resourceCache[filename] = img; - - return deferred.promise(); + }); }; var loadSound = function loadSound(filename) { - var deferred = $.Deferred(); - var audio = document.createElement("audio"); - var parts = filename.split("/"); - - var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); - if (!group || group.sounds.indexOf(parts[1].replace(".mp3", "")) === -1) { - deferred.resolve(); - return deferred; - } - - audio.preload = "auto"; - audio.oncanplaythrough = (function () { - resourceCache[filename] = audio; - deferred.resolve(); - }).bind(this); - audio.onerror = (function () { - deferred.resolve(); - }).bind(this); + return new Promise(function (resolve) { + var audio = document.createElement("audio"); + var parts = filename.split("/"); + + var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); + if (!group || group.sounds.indexOf(parts[1].replace(".mp3", "")) === -1) { + resolve(); + return; + } - audio.src = soundDir + filename; + audio.preload = "auto"; + audio.oncanplaythrough = function () { + resourceCache[filename] = audio; + resolve(); + }; + audio.onerror = function () { + resolve(); + }; - return deferred; + audio.src = soundDir + filename; + }); }; var promises = Object.keys(resources).map(function (filename) { @@ -1156,7 +1153,7 @@ var PJSCodeInjector = (function () { } }); - $.when.apply($, promises).then(function () { + Promise.all(promises).then(function () { var canvas = document.createElement("canvas"); canvas.width = 400; canvas.height = 400; @@ -2491,7 +2488,7 @@ PJSResourceCache.prototype.cacheResources = function (resources) { var promises = Object.keys(resources).map(function (filename) { return _this.loadResource(filename); }); - return $.when.apply($, promises); + return Promise.all(promises); }; PJSResourceCache.prototype.loadResource = function (filename) { @@ -2503,53 +2500,55 @@ PJSResourceCache.prototype.loadResource = function (filename) { }; PJSResourceCache.prototype.loadImage = function (filename) { - var deferred = $.Deferred(); - var path = this.output.imagesDir + filename; - var img = document.createElement("img"); - - img.onload = (function () { - this.cache[filename] = img; - deferred.resolve(); - }).bind(this); - img.onerror = (function () { - deferred.resolve(); // always resolve - }).bind(this); - - img.src = path; - this.imageHolder.appendChild(img); - - return deferred; + var _this2 = this; + + return new Promise(function (resolve) { + var path = _this2.output.imagesDir + filename; + var img = document.createElement("img"); + + img.onload = function () { + _this2.cache[filename] = img; + resolve(); + }; + img.onerror = function () { + resolve(); // always resolve + }; + + img.src = path; + _this2.imageHolder.appendChild(img); + }); }; PJSResourceCache.prototype.loadSound = function (filename) { - var deferred = $.Deferred(); - var audio = document.createElement("audio"); - var parts = filename.split("/"); - - var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); - var hasSound = group && group.sounds.includes(parts[1].replace(".mp3", "")); - if (!hasSound) { - deferred.resolve(); - return deferred; - } + var _this3 = this; - audio.preload = "auto"; - audio.oncanplaythrough = (function () { - this.cache[filename] = { - audio: audio, - __id: function __id() { - return "getSound('" + filename.replace(".mp3", "") + "')"; - } - }; - deferred.resolve(); - }).bind(this); - audio.onerror = (function () { - deferred.resolve(); - }).bind(this); + return new Promise(function (resolve) { + var audio = document.createElement("audio"); + var parts = filename.split("/"); + + var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); + var hasSound = group && group.sounds.includes(parts[1].replace(".mp3", "")); + if (!hasSound) { + resolve(); + return; + } - audio.src = this.output.soundsDir + filename; + audio.preload = "auto"; + audio.oncanplaythrough = function () { + _this3.cache[filename] = { + audio: audio, + __id: function __id() { + return "getSound('" + filename.replace(".mp3", "") + "')"; + } + }; + resolve(); + }; + audio.onerror = function () { + resolve(); + }; - return deferred; + audio.src = _this3.output.soundsDir + filename; + }); }; PJSResourceCache.prototype.getResource = function (filename, type) { diff --git a/js/output/pjs/pjs-code-injector.js b/js/output/pjs/pjs-code-injector.js index 6c1b35ced..fe298172b 100644 --- a/js/output/pjs/pjs-code-injector.js +++ b/js/output/pjs/pjs-code-injector.js @@ -334,36 +334,35 @@ class PJSCodeInjector { * * @param {string} userCode: code to lint * @param {boolean} skip: skips linting if true and resolves Deferred immediately - * @returns {$.Deferred} resolves an array of lint errors + * @returns {Promise} resolves an array of lint errors */ lint(userCode, skip) { - var deferred = $.Deferred(); - if (skip || !userCode) { - deferred.resolve([]); - return deferred; - } + return new Promise((resolve) => { + if (skip || !userCode) { + resolve([]); + return; + } - // Build a string of options to feed into JSHint - // All properties are defined in the config - var hintCode = `/*jshint ${this.propListString(this.JSHint)} */` + + // Build a string of options to feed into JSHint + // All properties are defined in the config + var hintCode = `/*jshint ${this.propListString(this.JSHint)} */` + - // Build a string of variables names to feed into JSHint - // This lets JSHint know which variables are globally exposed - // and which can be overridden, more details: - // http://www.jshint.com/about/ - // propName: true (is a global property, but can be overridden) - // propName: false (is a global property, cannot be overridden) - `/*global ${this.propListString(this.props)} */\n` + + // Build a string of variables names to feed into JSHint + // This lets JSHint know which variables are globally exposed + // and which can be overridden, more details: + // http://www.jshint.com/about/ + // propName: true (is a global property, but can be overridden) + // propName: false (is a global property, cannot be overridden) + `/*global ${this.propListString(this.props)} */\n` + - // The user's code to execute - userCode; + // The user's code to execute + userCode; - this.hintWorker.exec(hintCode, (hintData, hintErrors) => { - this.globals = this.extractGlobals(hintData); - deferred.resolve(hintErrors); + this.hintWorker.exec(hintCode, (hintData, hintErrors) => { + this.globals = this.extractGlobals(hintData); + resolve(hintErrors); + }); }); - - return deferred; } /** @@ -407,9 +406,9 @@ class PJSCodeInjector { // Make sure the object actually exists before we try // to inject stuff into it if (!this.processing[name]) { - if ($.isArray(obj)) { + if (Array.isArray(obj)) { this.processing[name] = []; - } else if ($.isFunction(obj)) { + } else if (typeof obj === "function") { this.processing[name] = function() {}; } else { this.processing[name] = {}; @@ -1062,46 +1061,44 @@ class PJSCodeInjector { document.body.appendChild(imageHolder); var loadImage = function(filename) { - var deferred = $.Deferred(); - var img = document.createElement("img"); - img.onload = function() { + return new Promise((resolve) => { + var img = document.createElement("img"); + img.onload = function() { + resourceCache[filename] = img; + resolve(); + }; + img.onerror = function() { + resolve(); // always resolve + }; + + img.src = imageDir + filename; + imageHolder.appendChild(img); resourceCache[filename] = img; - deferred.resolve(); - }.bind(this); - img.onerror = function() { - deferred.resolve(); // always resolve - }.bind(this); - - img.src = imageDir + filename; - imageHolder.appendChild(img); - resourceCache[filename] = img; - - return deferred.promise(); + }); }; var loadSound = function(filename) { - var deferred = $.Deferred(); - var audio = document.createElement("audio"); - var parts = filename.split("/"); - - var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); - if (!group || group.sounds.indexOf(parts[1].replace(".mp3", "")) === -1) { - deferred.resolve(); - return deferred; - } - - audio.preload = "auto"; - audio.oncanplaythrough = function() { - resourceCache[filename] = audio; - deferred.resolve(); - }.bind(this); - audio.onerror = function() { - deferred.resolve(); - }.bind(this); - - audio.src = soundDir + filename; + return new Promise((resolve) => { + var audio = document.createElement("audio"); + var parts = filename.split("/"); + + var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); + if (!group || group.sounds.indexOf(parts[1].replace(".mp3", "")) === -1) { + resolve(); + return; + } - return deferred; + audio.preload = "auto"; + audio.oncanplaythrough = function() { + resourceCache[filename] = audio; + resolve(); + }; + audio.onerror = function() { + resolve(); + }; + + audio.src = soundDir + filename; + }); }; var promises = Object.keys(resources).map(function(filename) { @@ -1112,7 +1109,7 @@ class PJSCodeInjector { } }); - $.when.apply($, promises).then(function() { + Promise.all(promises).then(function() { var canvas = document.createElement('canvas'); canvas.width = 400; canvas.height = 400; diff --git a/js/output/pjs/pjs-resource-cache.js b/js/output/pjs/pjs-resource-cache.js index 92a3cf952..0ed3cbe43 100644 --- a/js/output/pjs/pjs-resource-cache.js +++ b/js/output/pjs/pjs-resource-cache.js @@ -31,7 +31,7 @@ PJSResourceCache.prototype.cacheResources = function(resources) { var promises = Object.keys(resources).map((filename) => { return this.loadResource(filename); }); - return $.when.apply($, promises); + return Promise.all(promises); }; PJSResourceCache.prototype.loadResource = function(filename) { @@ -43,53 +43,51 @@ PJSResourceCache.prototype.loadResource = function(filename) { }; PJSResourceCache.prototype.loadImage = function(filename) { - var deferred = $.Deferred(); - var path = this.output.imagesDir + filename; - var img = document.createElement("img"); - - img.onload = function() { - this.cache[filename] = img; - deferred.resolve(); - }.bind(this); - img.onerror = function() { - deferred.resolve(); // always resolve - }.bind(this); - - img.src = path; - this.imageHolder.appendChild(img); - - return deferred; + return new Promise((resolve) => { + var path = this.output.imagesDir + filename; + var img = document.createElement("img"); + + img.onload = () => { + this.cache[filename] = img; + resolve(); + }; + img.onerror = () => { + resolve(); // always resolve + }; + + img.src = path; + this.imageHolder.appendChild(img); + }); }; PJSResourceCache.prototype.loadSound = function(filename) { - var deferred = $.Deferred(); - var audio = document.createElement("audio"); - var parts = filename.split("/"); - - var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); - var hasSound = group && group.sounds.includes(parts[1].replace(".mp3", "")); - if (!hasSound) { - deferred.resolve(); - return deferred; - } - - audio.preload = "auto"; - audio.oncanplaythrough = function() { - this.cache[filename] = { - audio: audio, - __id: function () { - return `getSound('${filename.replace(".mp3", "")}')`; - } + return new Promise((resolve) => { + var audio = document.createElement("audio"); + var parts = filename.split("/"); + + var group = _.findWhere(OutputSounds[0].groups, { groupName: parts[0] }); + var hasSound = group && group.sounds.includes(parts[1].replace(".mp3", "")); + if (!hasSound) { + resolve(); + return; + } + + audio.preload = "auto"; + audio.oncanplaythrough = () => { + this.cache[filename] = { + audio: audio, + __id: function () { + return `getSound('${filename.replace(".mp3", "")}')`; + } + }; + resolve(); + }; + audio.onerror = () => { + resolve(); }; - deferred.resolve(); - }.bind(this); - audio.onerror = function() { - deferred.resolve(); - }.bind(this); - - audio.src = this.output.soundsDir + filename; - return deferred; + audio.src = this.output.soundsDir + filename; + }); }; PJSResourceCache.prototype.getResource = function(filename, type) {