diff --git a/notebook/static/base/js/utils.js b/notebook/static/base/js/utils.js index 30e355f81..d53b219ec 100644 --- a/notebook/static/base/js/utils.js +++ b/notebook/static/base/js/utils.js @@ -10,34 +10,37 @@ define([ ], function($, CodeMirror, moment){ "use strict"; - var load_extensions = function () { - // load one or more Jupyter notebook extensions with requirejs - - var extensions = []; - var extension_names = arguments; - for (var i = 0; i < extension_names.length; i++) { - extensions.push("nbextensions/" + arguments[i]); - } - - require(extensions, - function () { - for (var i = 0; i < arguments.length; i++) { - var ext = arguments[i]; - var ext_name = extension_names[i]; - // success callback - console.log("Loaded extension: " + ext_name); - if (ext && ext.load_ipython_extension !== undefined) { - ext.load_ipython_extension(); - } + /** + * Load a single extension. + * @param {string} extension - extension path. + * @return {Promise} that resolves to an extension module handle + */ + var load_extension = function (extension) { + return new Promise(function(resolve, reject) { + require(["nbextensions/" + extension], function(module) { + console.log("Loaded extension: " + extension); + try { + module.load_ipython_extension(); + } finally { + resolve(module); } - }, - function (err) { - // failure callback - console.log("Failed to load extension(s):", err.requireModules, err); - } - ); + }, function(err) { + reject(err); + }); + }); }; - + + /** + * Load multiple extensions. + * Takes n-args, where each arg is a string path to the extension. + * @return {Promise} that resolves to a list of loaded module handles. + */ + var load_extensions = function () { + return Promise.all(Array.prototype.map.call(arguments, load_extension)).catch(function(err) { + console.error("Failed to load extension" + (err.requireModules.length>1?'s':'') + ":", err.requireModules, err); + }); + }; + /** * Wait for a config section to load, and then load the extensions specified * in a 'load_extensions' key inside it. diff --git a/notebook/tests/base/utils.js b/notebook/tests/base/utils.js index fe5c878fe..624983ba2 100644 --- a/notebook/tests/base/utils.js +++ b/notebook/tests/base/utils.js @@ -20,4 +20,20 @@ casper.notebook_test(function () { }, input); this.test.assertEquals(result, output, "IPython.utils.fixConsole() handles [0m correctly"); + + this.thenEvaluate(function() { + define('nbextensions/a', [], function() { window.a = true; }); + define('nbextensions/c', [], function() { window.c = true; }); + require(['base/js/utils'], function(utils) { + utils.load_extensions('a', 'b', 'c'); + }); + }).then(function() { + this.waitFor(function() { + return this.evaluate(function() { return window.a; }); + }); + + this.waitFor(function() { + return this.evaluate(function() { return window.a; }); + }); + }); });