diff --git a/notebook/notebookapp.py b/notebook/notebookapp.py index e070069f30..24aa7c2283 100644 --- a/notebook/notebookapp.py +++ b/notebook/notebookapp.py @@ -137,16 +137,6 @@ def load_handlers(name): mod = __import__(name, fromlist=['default_handlers']) return mod.default_handlers - -class DeprecationHandler(IPythonHandler): - def get(self, url_path): - self.set_header("Content-Type", 'text/javascript') - self.finish(""" - console.warn('`/static/widgets/js` is deprecated. Use `nbextensions/widgets/widgets/js` instead.'); - define(['%s'], function(x) { return x; }); - """ % url_path_join('nbextensions', 'widgets', 'widgets', url_path.rstrip('.js'))) - self.log.warning('Deprecated widget Javascript path /static/widgets/js/*.js was used') - #----------------------------------------------------------------------------- # The Tornado web application #----------------------------------------------------------------------------- @@ -262,7 +252,6 @@ def init_handlers(self, settings): # Order matters. The first handler to match the URL will handle the request. handlers = [] - handlers.append((r'/deprecatedwidgets/(.*)', DeprecationHandler)) handlers.extend(load_handlers('tree.handlers')) handlers.extend([(r"/login", settings['login_handler_class'])]) handlers.extend([(r"/logout", settings['logout_handler_class'])]) @@ -282,21 +271,21 @@ def init_handlers(self, settings): handlers.extend(load_handlers('lab.handlers')) # BEGIN HARDCODED WIDGETS HACK + # TODO: Remove on notebook 5.0 widgets = None try: - import widgetsnbextension as widgets + import widgetsnbextension except: try: import ipywidgets as widgets + handlers.append( + (r"/nbextensions/widgets/(.*)", FileFindHandler, { + 'path': widgets.find_static_assets(), + 'no_cache_paths': ['/'], # don't cache anything in nbextensions + }), + ) except: app_log.warning('Widgets are unavailable. Please install widgetsnbextension or ipywidgets 4.0') - if widgets is not None: - handlers.append( - (r"/nbextensions/widgets/(.*)", FileFindHandler, { - 'path': widgets.find_static_assets(), - 'no_cache_paths': ['/'], # don't cache anything in nbextensions - }), - ) # END HARDCODED WIDGETS HACK handlers.append( diff --git a/notebook/static/base/js/utils.js b/notebook/static/base/js/utils.js index 873e962499..49178cfd4f 100644 --- a/notebook/static/base/js/utils.js +++ b/notebook/static/base/js/utils.js @@ -13,6 +13,16 @@ define([ // keep track of which extensions have been loaded already var extensions_loaded = []; + /** + * Whether or not an extension has been loaded + * @param {string} extension - name of the extension + * @return {boolean} true if loaded already + */ + var is_loaded = function(extension) { + var ext_path = "nbextensions/" + extension; + return extensions_loaded.indexOf(ext_path) >= 0; + }; + /** * Load a single extension. * @param {string} extension - extension path. @@ -22,16 +32,16 @@ define([ return new Promise(function(resolve, reject) { var ext_path = "nbextensions/" + extension; requirejs([ext_path], function(module) { - try { - if (extensions_loaded.indexOf(ext_path) < 0) { - console.log("Loading extension: " + extension); - module.load_ipython_extension(); - extensions_loaded.push(ext_path); + if (!is_loaded(extension)) { + console.log("Loading extension: " + extension); + if (module.load_ipython_extension) { + Promise.resolve(module.load_ipython_extension()).then(function() { + resolve(module); + }).catch(reject); } - else{ - console.log("Loaded extension already: " + extension); - } - } finally { + extensions_loaded.push(ext_path); + } else { + console.log("Loaded extension already: " + extension); resolve(module); } }, function(err) { @@ -54,8 +64,8 @@ define([ /** * Return a list of extensions that should be active - * The config for nbextensions comes in as a dict where keys are - * nbextensions paths and the values are a bool indicating if it + * The config for nbextensions comes in as a dict where keys are + * nbextensions paths and the values are a bool indicating if it * should be active. This returns a list of nbextension paths * where the value is true */ @@ -72,12 +82,12 @@ define([ * in a 'load_extensions' key inside it. */ function load_extensions_from_config(section) { - section.loaded.then(function() { + return section.loaded.then(function() { if (section.data.load_extensions) { var active = filter_extensions(section.data.load_extensions); - load_extensions.apply(this, active); + return load_extensions.apply(this, active); } - }); + }).catch(utils.reject('Could not load nbextensions from ' + section.section_name + ' config file')); } //============================================================================ @@ -937,6 +947,7 @@ define([ }; var utils = { + is_loaded: is_loaded, load_extension: load_extension, load_extensions: load_extensions, filter_extensions: filter_extensions, diff --git a/notebook/static/notebook/js/main.js b/notebook/static/notebook/js/main.js index d972a7f9f7..875d38e275 100644 --- a/notebook/static/notebook/js/main.js +++ b/notebook/static/notebook/js/main.js @@ -53,21 +53,12 @@ require([ requirejs(['custom/custom'], function() {}); - // BEGIN HARDCODED WIDGETS HACK - // Try to load the new extension - utils.load_extension('widgets/extension').catch(function () { - // Fallback to the ipywidgets extension - utils.load_extension('widgets/notebook/js/extension').catch(function () { - console.warn('Widgets are not available. Please install widgetsnbextension or ipywidgets 4.0'); - }); - }); - // END HARDCODED WIDGETS HACK - // compat with old IPython, remove for IPython > 3.0 window.CodeMirror = CodeMirror; // Setup all of the config related things + var common_options = { ws_url : utils.get_body_data("wsUrl"), base_url : utils.get_body_data("baseUrl"), @@ -187,9 +178,28 @@ require([ configurable: false }); - // Now actually load nbextensions - utils.load_extensions_from_config(config_section); - utils.load_extensions_from_config(common_config); + // Now actually load nbextensionsload_extensions_from_config + Promise.all([ + utils.load_extensions_from_config(config_section), + utils.load_extensions_from_config(common_config), + ]) + .catch(function(error) { + console.error('Could not load nbextensions from user config files', error); + }) + // BEGIN HARDCODED WIDGETS HACK + .then(function() { + if (!utils.is_loaded('widgets/extension')) { + // Fallback to the ipywidgets extension + utils.load_extension('widgets/notebook/js/extension').catch(function () { + console.warn('Widgets are not available. Please install widgetsnbextension or ipywidgets 4.0'); + }); + } + }) + .catch(function(error) { + console.error('Could not load ipywidgets', error); + }); + // END HARDCODED WIDGETS HACK + notebook.load_notebook(common_options.notebook_path); }); diff --git a/notebook/templates/lab.html b/notebook/templates/lab.html index 9d10ce9aea..7fedd8c1b1 100644 --- a/notebook/templates/lab.html +++ b/notebook/templates/lab.html @@ -23,7 +23,6 @@ {% endif %} custom : '{{ base_url }}custom', nbextensions : '{{ base_url }}nbextensions', - widgets : '{{ base_url }}deprecatedwidgets', kernelspecs : '{{ base_url }}kernelspecs', underscore : 'components/underscore/underscore-min', backbone : 'components/backbone/backbone-min', diff --git a/notebook/templates/page.html b/notebook/templates/page.html index 1f367fef97..cdec96146a 100644 --- a/notebook/templates/page.html +++ b/notebook/templates/page.html @@ -33,7 +33,6 @@ 'auth/js/main': 'auth/js/built/main.min', custom : '{{ base_url }}custom', nbextensions : '{{ base_url }}nbextensions', - widgets : '{{ base_url }}deprecatedwidgets', kernelspecs : '{{ base_url }}kernelspecs', underscore : 'components/underscore/underscore-min', backbone : 'components/backbone/backbone-min',