From 00ef5b13146970b003d22afbdd985280d4a05ee8 Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Tue, 29 Mar 2016 15:56:28 -0700 Subject: [PATCH 1/5] Downgraded ipywidget hack Fixed whitespace for jon's PR #1278 --- notebook/notebookapp.py | 10 +++---- notebook/static/base/js/utils.js | 41 ++++++++++++++++++----------- notebook/static/notebook/js/main.js | 27 ++++++++++--------- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/notebook/notebookapp.py b/notebook/notebookapp.py index e070069f30..c11e124709 100644 --- a/notebook/notebookapp.py +++ b/notebook/notebookapp.py @@ -284,19 +284,15 @@ def init_handlers(self, settings): # BEGIN HARDCODED WIDGETS HACK widgets = None try: - import widgetsnbextension as widgets - except: - try: - import ipywidgets as widgets - except: - app_log.warning('Widgets are unavailable. Please install widgetsnbextension or ipywidgets 4.0') - if widgets is not None: + 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') # END HARDCODED WIDGETS HACK handlers.append( diff --git a/notebook/static/base/js/utils.js b/notebook/static/base/js/utils.js index 873e962499..949eaf73de 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,14 @@ 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); - } - else{ - console.log("Loaded extension already: " + extension); - } - } finally { + if (is_loaded(extension)) { + console.log("Loading extension: " + extension); + Promise.resolve(module.load_ipython_extension()).then(function() { + resolve(module); + }).catch(reject); + extensions_loaded.push(ext_path); + } else { + console.log("Loaded extension already: " + extension); resolve(module); } }, function(err) { @@ -47,15 +55,17 @@ define([ */ var load_extensions = function () { console.log('load_extensions', arguments); - return Promise.all(Array.prototype.map.call(arguments, load_extension)).catch(function(err) { + + var args = Array.prototype.splice.apply(arguments); + return Promise.all(args.map(load_extension)).catch(function(err) { console.error("Failed to load extension" + (err.requireModules.length>1?'s':'') + ":", err.requireModules, err); }); }; /** * 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,10 +82,10 @@ 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); } }); } @@ -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..8560000d63 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"), @@ -188,8 +179,20 @@ require([ }); // Now actually load nbextensions - utils.load_extensions_from_config(config_section); - utils.load_extensions_from_config(common_config); + Promise.all([ + utils.load_extensions_from_config(config_section), + utils.load_extensions_from_config(common_config), + ]).then(function() { + // BEGIN HARDCODED WIDGETS HACK + 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'); + }); + } + // END HARDCODED WIDGETS HACK + }); + notebook.load_notebook(common_options.notebook_path); }); From 705992b6a62d7b540531b57acc503076129d734f Mon Sep 17 00:00:00 2001 From: Peter Parente Date: Tue, 29 Mar 2016 16:12:59 -0700 Subject: [PATCH 2/5] Fix is_loaded semantics --- notebook/static/base/js/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notebook/static/base/js/utils.js b/notebook/static/base/js/utils.js index 949eaf73de..e018ed9be7 100644 --- a/notebook/static/base/js/utils.js +++ b/notebook/static/base/js/utils.js @@ -20,7 +20,7 @@ define([ */ var is_loaded = function(extension) { var ext_path = "nbextensions/" + extension; - return extensions_loaded.indexOf(ext_path) < 0; + return extensions_loaded.indexOf(ext_path) >= 0; }; /** @@ -32,7 +32,7 @@ define([ return new Promise(function(resolve, reject) { var ext_path = "nbextensions/" + extension; requirejs([ext_path], function(module) { - if (is_loaded(extension)) { + if (!is_loaded(extension)) { console.log("Loading extension: " + extension); Promise.resolve(module.load_ipython_extension()).then(function() { resolve(module); From 255e5888fccd28f85b29c36b149a12741f664d66 Mon Sep 17 00:00:00 2001 From: Jonathan Frederic Date: Tue, 29 Mar 2016 16:55:10 -0700 Subject: [PATCH 3/5] Revert fancy pants changes --- notebook/notebookapp.py | 11 ----------- notebook/static/base/js/utils.js | 14 +++++++------- notebook/static/notebook/js/main.js | 15 +++++++++++---- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/notebook/notebookapp.py b/notebook/notebookapp.py index c11e124709..49f5465132 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'])]) diff --git a/notebook/static/base/js/utils.js b/notebook/static/base/js/utils.js index e018ed9be7..49178cfd4f 100644 --- a/notebook/static/base/js/utils.js +++ b/notebook/static/base/js/utils.js @@ -34,9 +34,11 @@ define([ requirejs([ext_path], function(module) { if (!is_loaded(extension)) { console.log("Loading extension: " + extension); - Promise.resolve(module.load_ipython_extension()).then(function() { - resolve(module); - }).catch(reject); + if (module.load_ipython_extension) { + Promise.resolve(module.load_ipython_extension()).then(function() { + resolve(module); + }).catch(reject); + } extensions_loaded.push(ext_path); } else { console.log("Loaded extension already: " + extension); @@ -55,9 +57,7 @@ define([ */ var load_extensions = function () { console.log('load_extensions', arguments); - - var args = Array.prototype.splice.apply(arguments); - return Promise.all(args.map(load_extension)).catch(function(err) { + 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); }); }; @@ -87,7 +87,7 @@ define([ var active = filter_extensions(section.data.load_extensions); return load_extensions.apply(this, active); } - }); + }).catch(utils.reject('Could not load nbextensions from ' + section.section_name + ' config file')); } //============================================================================ diff --git a/notebook/static/notebook/js/main.js b/notebook/static/notebook/js/main.js index 8560000d63..875d38e275 100644 --- a/notebook/static/notebook/js/main.js +++ b/notebook/static/notebook/js/main.js @@ -178,20 +178,27 @@ require([ configurable: false }); - // Now actually load nbextensions + // Now actually load nbextensionsload_extensions_from_config Promise.all([ utils.load_extensions_from_config(config_section), utils.load_extensions_from_config(common_config), - ]).then(function() { - // BEGIN HARDCODED WIDGETS HACK + ]) + .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'); }); } - // END HARDCODED WIDGETS HACK + }) + .catch(function(error) { + console.error('Could not load ipywidgets', error); }); + // END HARDCODED WIDGETS HACK notebook.load_notebook(common_options.notebook_path); From 7695311668d200c35efc119942f4f2912edfe21d Mon Sep 17 00:00:00 2001 From: Jonathan Frederic Date: Wed, 30 Mar 2016 16:27:14 -0700 Subject: [PATCH 4/5] Fix horrible horrible widget with a more horrible hack :poop: --- notebook/notebookapp.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/notebook/notebookapp.py b/notebook/notebookapp.py index 49f5465132..24aa7c2283 100644 --- a/notebook/notebookapp.py +++ b/notebook/notebookapp.py @@ -271,17 +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 ipywidgets as widgets - handlers.append( - (r"/nbextensions/widgets/(.*)", FileFindHandler, { - 'path': widgets.find_static_assets(), - 'no_cache_paths': ['/'], # don't cache anything in nbextensions - }), - ) + import widgetsnbextension except: - app_log.warning('Widgets are unavailable. Please install widgetsnbextension or ipywidgets 4.0') + 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') # END HARDCODED WIDGETS HACK handlers.append( From 9f9bc69e9bc6bdbaaa983cf0fb21335527a77f28 Mon Sep 17 00:00:00 2001 From: Jonathan Frederic Date: Wed, 30 Mar 2016 16:29:44 -0700 Subject: [PATCH 5/5] Remove deprecatedwidgets handler, because it's backwards compat support for ipywidgets 3.0 --- notebook/templates/lab.html | 1 - notebook/templates/page.html | 1 - 2 files changed, 2 deletions(-) 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',