Load modules individually, so a missing module doesn't 💩 on everything.

This commit is contained in:
Jonathan Frederic 2015-07-11 10:36:57 -05:00
parent cead281f26
commit f5296808ff

View File

@ -9,35 +9,42 @@ define([
'codemirror/mode/meta',
], function($, CodeMirror, moment){
"use strict";
/**
* 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([extension], function(module) {
console.log("Loaded extension: " + extension);
resolve(module);
}, 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 () {
// 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();
}
}
},
function (err) {
// failure callback
console.log("Failed to load extension(s):", err.requireModules, err);
}
);
return Promise.all(extensions.map(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.
@ -195,7 +202,7 @@ define([
//Map from terminal commands to CSS classes
var ansi_colormap = {
"01":"ansibold",
"30":"ansiblack",
"31":"ansired",
"32":"ansigreen",
@ -204,7 +211,7 @@ define([
"35":"ansipurple",
"36":"ansicyan",
"37":"ansigray",
"40":"ansibgblack",
"41":"ansibgred",
"42":"ansibggreen",
@ -214,7 +221,7 @@ define([
"46":"ansibgcyan",
"47":"ansibggray"
};
function _process_numbers(attrs, numbers) {
// process ansi escapes
var n = numbers.shift();
@ -230,7 +237,7 @@ define([
console.log("Not enough fields for VT100 color", numbers);
return;
}
var index_or_rgb = numbers.shift();
var r,g,b;
if (index_or_rgb == "5") {
@ -337,7 +344,7 @@ define([
// all ANSI codes that do not end with "m".
var ignored_re = /(?=(\033\[[\d;=]*[a-ln-zA-Z]{1}))\1(?!m)/g;
txt = txt.replace(ignored_re, "");
// color ansi codes
txt = ansispan(txt);
return txt;
@ -371,7 +378,7 @@ define([
test.remove();
return Math.floor(points*pixel_per_point);
};
var always_new = function (constructor) {
/**
* wrapper around contructor to avoid requiring `var a = new constructor()`
@ -404,13 +411,13 @@ define([
url = url.replace(/\/\/+/, '/');
return url;
};
var url_path_split = function (path) {
/**
* Like os.path.split for URLs.
* Always returns two strings, the directory path and the base filename
*/
var idx = path.lastIndexOf('/');
if (idx === -1) {
return ['', path];
@ -418,7 +425,7 @@ define([
return [ path.slice(0, idx), path.slice(idx + 1) ];
}
};
var parse_url = function (url) {
/**
* an `a` element with an href allows attr-access to the parsed segments of a URL
@ -434,7 +441,7 @@ define([
a.href = url;
return a;
};
var encode_uri_components = function (uri) {
/**
* encode just the components of a multi-segment uri,
@ -442,7 +449,7 @@ define([
*/
return uri.split('/').map(encodeURIComponent).join('/');
};
var url_join_encode = function () {
/**
* join a sequence of url components with '/',
@ -485,7 +492,7 @@ define([
return val;
return decodeURIComponent(val);
};
var to_absolute_cursor_pos = function (cm, cursor) {
/**
* get the absolute cursor position from CodeMirror's col, ch
@ -499,7 +506,7 @@ define([
}
return cursor_pos;
};
var from_absolute_cursor_pos = function (cm, cursor_pos) {
/**
* turn absolute cursor position into CodeMirror col, ch cursor
@ -523,7 +530,7 @@ define([
ch : line.length - 1,
};
};
// http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
var browser = (function() {
if (typeof navigator === 'undefined') {
@ -550,7 +557,7 @@ define([
if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux";
return OSName;
})();
var get_url_param = function (name) {
// get a URL parameter. I cannot believe we actually need this.
// Based on http://stackoverflow.com/a/25359264/938949
@ -559,7 +566,7 @@ define([
return decodeURIComponent(match[1] || '');
}
};
var is_or_has = function (a, b) {
/**
* Is b a child of a or a itself?
@ -583,13 +590,13 @@ define([
return false;
}
};
var mergeopt = function(_class, options, overwrite){
options = options || {};
overwrite = overwrite || {};
return $.extend(true, {}, _class.options_default, options, overwrite);
};
var ajax_error_msg = function (jqXHR) {
/**
* Return a JSON error message if there is one,
@ -614,7 +621,7 @@ define([
};
var requireCodeMirrorMode = function (mode, callback, errback) {
/**
/**
* find a predefined mode or detect from CM metadata then
* require and callback with the resolveable mode string: mime or
* custom name
@ -648,10 +655,10 @@ define([
}, errback
);
};
/** Error type for wrapped XHR errors. */
var XHR_ERROR = 'XhrError';
/**
* Wraps an AJAX error as an Error object.
*/
@ -664,7 +671,7 @@ define([
wrapped_error.xhr_error = error;
return wrapped_error;
};
var promising_ajax = function(url, settings) {
/**
* Like $.ajax, but returning an ES6 promise. success and error settings
@ -717,8 +724,8 @@ define([
/**
* Tries to load a class
*
* Tries to load a class from a module using require.js, if a module
* is specified, otherwise tries to load a class from the global
* Tries to load a class from a module using require.js, if a module
* is specified, otherwise tries to load a class from the global
* registry, if the global registry is provided.
*/
return new Promise(function(resolve, reject) {
@ -764,15 +771,15 @@ define([
var reject = function(message, log) {
/**
* Creates a wrappable Promise rejection function.
*
*
* Creates a function that returns a Promise.reject with a new WrappedError
* that has the provided message and wraps the original error that
* that has the provided message and wraps the original error that
* caused the promise to reject.
*/
return function(error) {
return function(error) {
var wrapped_error = new WrappedError(message, error);
if (log) console.error(wrapped_error);
return Promise.reject(wrapped_error);
if (log) console.error(wrapped_error);
return Promise.reject(wrapped_error);
};
};
@ -802,14 +809,14 @@ define([
return MathJax.Hub.Queue(["Typeset", MathJax.Hub, this]);
});
};
var time = {};
time.milliseconds = {};
time.milliseconds.s = 1000;
time.milliseconds.m = 60 * time.milliseconds.s;
time.milliseconds.h = 60 * time.milliseconds.m;
time.milliseconds.d = 24 * time.milliseconds.h;
time.thresholds = {
// moment.js thresholds in milliseconds
s: moment.relativeTimeThreshold('s') * time.milliseconds.s,
@ -817,14 +824,14 @@ define([
h: moment.relativeTimeThreshold('h') * time.milliseconds.h,
d: moment.relativeTimeThreshold('d') * time.milliseconds.d,
};
time.timeout_from_dt = function (dt) {
/** compute a timeout based on dt
input and output both in milliseconds
use moment's relative time thresholds:
- 10 seconds if in 'seconds ago' territory
- 1 minute if in 'minutes ago'
- 1 hour otherwise
@ -837,7 +844,7 @@ define([
return time.milliseconds.h;
}
};
var utils = {
load_extensions: load_extensions,
load_extensions_from_config: load_extensions_from_config,
@ -879,4 +886,4 @@ define([
};
return utils;
});
});