##// END OF EJS Templates
Reverse hscrollbar min-height hack on OS X...
Reverse hscrollbar min-height hack on OS X OS X has optional behavior to only draw scrollbars during scroll, which causes problems for CodeMirror's scrollbars. CodeMirror's solution is to set a minimum size for their scrollbars, which is always present. The trade is that the container overlays most of the last line, swallowing click events when there is scrolling to do, even when no scrollbar is visible. This reverses the trade, recovering the click events at the expense of never showing the horizontal scrollbar on OS X when this option is enabled.

File last commit:

r20290:641ea822
r20298:2907e856
Show More
kernelselector.js
325 lines | 11.7 KiB | application/javascript | JavascriptLexer
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 // Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
define([
'jquery',
Min RK
fix new-notebook and change-kernel menus...
r19916 'base/js/namespace',
'base/js/dialog',
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 'base/js/utils',
Min RK
fix new-notebook and change-kernel menus...
r19916 ], function($, IPython, dialog, utils) {
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 "use strict";
var KernelSelector = function(selector, notebook) {
Min RK
use promises to wait for kernelspecs on notebook load...
r19884 var that = this;
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 this.selector = selector;
this.notebook = notebook;
Bussonnier Matthias
move setting nb.kernelselector inside kernelselector itself
r19448 this.notebook.set_kernelselector(this);
Thomas Kluyver
Use JS events for switching kernelspecs
r17380 this.events = notebook.events;
MinRK
allow kernel_name to be undefined in js...
r18032 this.current_selection = null;
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 this.kernelspecs = {};
if (this.selector !== undefined) {
this.element = $(selector);
this.request_kernelspecs();
}
Thomas Kluyver
Use JS events for switching kernelspecs
r17380 this.bind_events();
Thomas Kluyver
Address review comments
r17392 // Make the object globally available for user convenience & inspection
IPython.kernelselector = this;
Min RK
use promises to wait for kernelspecs on notebook load...
r19884 this._finish_load = null;
Min RK
handle missing kernel...
r20192 this._loaded = false;
Min RK
replace project_name with language_name...
r20193 this.loaded = new Promise(function(resolve) {
Min RK
use promises to wait for kernelspecs on notebook load...
r19884 that._finish_load = resolve;
});
Matthias BUSSONNIER
load the per kernel kernel.js and kernel.css...
r19404 Object.seal(this);
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 };
KernelSelector.prototype.request_kernelspecs = function() {
var url = utils.url_join_encode(this.notebook.base_url, 'api/kernelspecs');
Min RK
kernelspecs is a dict...
r19263 utils.promising_ajax(url).then($.proxy(this._got_kernelspecs, this));
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 };
Min RK
replace project_name with language_name...
r20193 var _sorted_names = function(kernelspecs) {
// sort kernel names
return Object.keys(kernelspecs).sort(function (a, b) {
Min RK
kernelspecs is a dict...
r19263 // sort by display_name
Min RK
replace project_name with language_name...
r20193 var da = kernelspecs[a].spec.display_name;
var db = kernelspecs[b].spec.display_name;
Min RK
kernelspecs is a dict...
r19263 if (da === db) {
return 0;
} else if (da > db) {
return 1;
} else {
return -1;
}
});
Min RK
replace project_name with language_name...
r20193 };
KernelSelector.prototype._got_kernelspecs = function(data) {
var that = this;
this.kernelspecs = data.kernelspecs;
var change_kernel_submenu = $("#menu-change-kernel-submenu");
var new_notebook_submenu = $("#menu-new-notebook-submenu");
var keys = _sorted_names(data.kernelspecs);
Min RK
kernelselector lint
r19887
Min RK
fix new-notebook and change-kernel menus...
r19916 keys.map(function (key) {
// Create the Kernel > Change kernel submenu
var ks = data.kernelspecs[key];
change_kernel_submenu.append(
$("<li>").attr("id", "kernel-submenu-"+ks.name).append(
$('<a>')
.attr('href', '#')
.click( function () {
that.set_kernel(ks.name);
})
.text(ks.spec.display_name)
)
);
// Create the File > New Notebook submenu
new_notebook_submenu.append(
$("<li>").attr("id", "new-notebook-submenu-"+ks.name).append(
$('<a>')
.attr('href', '#')
.click( function () {
that.new_notebook(ks.name);
})
.text(ks.spec.display_name)
)
);
});
Min RK
use promises to wait for kernelspecs on notebook load...
r19884 // trigger loaded promise
Min RK
handle missing kernel...
r20192 this._loaded = true;
Min RK
use promises to wait for kernelspecs on notebook load...
r19884 this._finish_load();
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 };
Min RK
load kernel js, css, logo on spec_changed event...
r19745
KernelSelector.prototype._spec_changed = function (event, ks) {
/** event handler for spec_changed */
// update selection
this.current_selection = ks.name;
Mathieu
put current kernel at the top
r19844 // put the current kernel at the top of File > New Notebook
var cur_kernel_entry = $("#new-notebook-submenu-" + ks.name);
Mathieu
fix kernel change breaking new notebook list
r19898 var parent = cur_kernel_entry.parent();
// do something only if there is more than one kernel
if (parent.children().length > 1) {
// first, sort back the submenu
parent.append(
parent.children("li[class!='divider']").sort(
function (a,b) {
var da = $("a",a).text();
var db = $("a",b).text();
if (da === db) {
return 0;
} else if (da > db) {
return 1;
} else {
return -1;
}}));
// then, if there is no divider yet, add one
if (!parent.children("li[class='divider']").length) {
parent.prepend($("<li>").attr("class","divider"));
}
// finally, put the current kernel at the top
parent.prepend(cur_kernel_entry);
Min RK
kernelselector lint
r19887 }
Mathieu
put current kernel at the top
r19844
Min RK
load kernel js, css, logo on spec_changed event...
r19745 // load logo
var logo_img = this.element.find("img.current_kernel_logo");
$("#kernel_indicator").find('.kernel_indicator_name').text(ks.spec.display_name);
if (ks.resources['logo-64x64']) {
logo_img.attr("src", ks.resources['logo-64x64']);
logo_img.show();
} else {
logo_img.hide();
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 }
Min RK
add resource URLs to kernelspec model...
r19681
Min RK
load kernel js, css, logo on spec_changed event...
r19745 // load kernel css
Min RK
add resource URLs to kernelspec model...
r19681 var css_url = ks.resources['kernel.css'];
if (css_url) {
$('#kernel-css').attr('href', css_url);
} else {
$('#kernel-css').attr('href', '');
}
Min RK
load kernel js, css, logo on spec_changed event...
r19745 // load kernel js
Min RK
add resource URLs to kernelspec model...
r19681 if (ks.resources['kernel.js']) {
require([ks.resources['kernel.js']],
function (kernel_mod) {
if (kernel_mod && kernel_mod.onload) {
kernel_mod.onload();
} else {
console.warn("Kernel " + ks.name + " has a kernel.js file that does not contain "+
"any asynchronous module definition. This is undefined behavior "+
"and not recommended.");
}
}, function (err) {
console.warn("Failed to load kernel.js from ", ks.resources['kernel.js'], err);
Matthias BUSSONNIER
load the per kernel kernel.js and kernel.css...
r19404 }
Min RK
add resource URLs to kernelspec model...
r19681 );
}
Min RK
load kernel js, css, logo on spec_changed event...
r19745 };
Min RK
add resource URLs to kernelspec model...
r19681
Min RK
handle missing kernel...
r20192 KernelSelector.prototype.set_kernel = function (selected) {
/** set the kernel by name, ensuring kernelspecs have been loaded, first
kernel can be just a kernel name, or a notebook kernelspec metadata
Min RK
s/language_name/language/
r20195 (name, language, display_name).
Min RK
handle missing kernel...
r20192 */
Min RK
cleanup kernelspec loading...
r19886 var that = this;
Min RK
handle missing kernel...
r20192 if (typeof selected === 'string') {
selected = {
name: selected
};
}
if (this._loaded) {
this._set_kernel(selected);
} else {
return this.loaded.then(function () {
that._set_kernel(selected);
});
}
Min RK
cleanup kernelspec loading...
r19886 };
Min RK
handle missing kernel...
r20192 KernelSelector.prototype._set_kernel = function (selected) {
Min RK
cleanup kernelspec loading...
r19886 /** Actually set the kernel (kernelspecs have been loaded) */
Min RK
handle missing kernel...
r20192 if (selected.name === this.current_selection) {
Min RK
cleanup kernelspec loading...
r19886 // only trigger event if value changed
Min RK
load kernel js, css, logo on spec_changed event...
r19745 return;
}
Min RK
replace project_name with language_name...
r20193 var kernelspecs = this.kernelspecs;
var ks = kernelspecs[selected.name];
Min RK
handle missing kernel...
r20192 if (ks === undefined) {
Min RK
replace project_name with language_name...
r20193 var available = _sorted_names(kernelspecs);
var matches = [];
Min RK
s/language_name/language/
r20195 if (selected.language && selected.language.length > 0) {
Min RK
use Array.map
r20197 available.map(function (name) {
Min RK
s/language_name/language/
r20195 if (kernelspecs[name].spec.language.toLowerCase() === selected.language.toLowerCase()) {
Min RK
replace project_name with language_name...
r20193 matches.push(name);
Min RK
handle missing kernel...
r20192 }
});
}
Min RK
replace project_name with language_name...
r20193 if (matches.length === 1) {
ks = kernelspecs[matches[0]];
Min RK
use one-off notification widget for match notification...
r20199 console.log("No exact match found for " + selected.name +
", using only kernel that matches language=" + selected.language, ks);
this.events.trigger("spec_match_found.Kernel", {
selected: selected,
found: ks,
});
Min RK
replace project_name with language_name...
r20193 }
Min RK
handle missing kernel...
r20192 // if still undefined, trigger failure event
if (ks === undefined) {
Min RK
replace project_name with language_name...
r20193 this.events.trigger("spec_not_found.Kernel", {
selected: selected,
matches: matches,
available: available,
});
Min RK
handle missing kernel...
r20192 return;
}
}
Min RK
don't prevent spec_changed from firing on load...
r20290 if (this.notebook._session_starting &&
this.notebook.session.kernel.name !== ks.name) {
Min RK
console.log
r19888 console.error("Cannot change kernel while waiting for pending session start.");
Min RK
load kernel js, css, logo on spec_changed event...
r19745 return;
}
Min RK
handle missing kernel...
r20192 this.current_selection = ks.name;
Min RK
load kernel js, css, logo on spec_changed event...
r19745 this.events.trigger('spec_changed.Kernel', ks);
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 };
Min RK
handle missing kernel...
r20192
KernelSelector.prototype._spec_not_found = function (event, data) {
var that = this;
var select = $("<select>").addClass('form-control');
console.warn("Kernelspec not found:", data);
Min RK
replace project_name with language_name...
r20193 var names;
if (data.matches.length > 1) {
names = data.matches;
} else {
names = data.available;
}
Min RK
use Array.map
r20197 names.map(function (name) {
Min RK
replace project_name with language_name...
r20193 var ks = that.kernelspecs[name];
Min RK
handle missing kernel...
r20192 select.append(
Min RK
replace project_name with language_name...
r20193 $('<option/>').attr('value', ks.name).text(ks.spec.display_name || ks.name)
Min RK
handle missing kernel...
r20192 );
});
var body = $("<form>").addClass("form-inline").append(
$("<span>").text(
Min RK
replace project_name with language_name...
r20193 "I couldn't find a kernel matching " + (data.selected.display_name || data.name) + "." +
Min RK
handle missing kernel...
r20192 " Please select a kernel:"
)
).append(select);
dialog.modal({
title : 'Kernel not found',
body : body,
buttons : {
Min RK
"Continue without kernel" button
r20198 'Continue without kernel' : {
Min RK
add "No appropriate kernel" button to kernel-selection prompt
r20194 class : 'btn-danger',
click : function () {
that.events.trigger('no_kernel.Kernel');
}
},
Min RK
handle missing kernel...
r20192 OK : {
class : 'btn-primary',
click : function () {
that.set_kernel(select.val());
}
}
}
});
};
Matthias BUSSONNIER
load the per kernel kernel.js and kernel.css...
r19404
Mathieu
add choice of kernel for new notebook
r19843 KernelSelector.prototype.new_notebook = function (kernel_name) {
var w = window.open();
// Create a new notebook in the same path as the current
// notebook's path.
var that = this;
var parent = utils.url_path_split(that.notebook.notebook_path)[0];
that.notebook.contents.new_untitled(parent, {type: "notebook"}).then(
function (data) {
var url = utils.url_join_encode(
that.notebook.base_url, 'notebooks', data.path
);
url += "?kernel_name=" + kernel_name;
w.location = url;
},
function(error) {
w.close();
dialog.modal({
title : 'Creating Notebook Failed',
body : "The error was: " + error.message,
buttons : {'OK' : {'class' : 'btn-primary'}}
});
}
);
};
Matthias BUSSONNIER
load the per kernel kernel.js and kernel.css...
r19404 KernelSelector.prototype.lock_switch = function() {
Matthias Bussonnier
adresses Min comments
r19406 // should set a flag and display warning+reload if user want to
// re-change kernel. As UI discussion never finish
// making that a separate PR.
Matthias Bussonnier
Fix typos, rephrase english. Thanks Kyle.
r19405 console.warn('switching kernel is not guaranteed to work !');
Matthias BUSSONNIER
load the per kernel kernel.js and kernel.css...
r19404 };
Thomas Kluyver
Use JS events for switching kernelspecs
r17380 KernelSelector.prototype.bind_events = function() {
var that = this;
Min RK
load kernel js, css, logo on spec_changed event...
r19745 this.events.on('spec_changed.Kernel', $.proxy(this._spec_changed, this));
Min RK
handle missing kernel...
r20192 this.events.on('spec_not_found.Kernel', $.proxy(this._spec_not_found, this));
Min RK
load kernel js, css, logo on spec_changed event...
r19745 this.events.on('kernel_created.Session', function (event, data) {
Min RK
cleanup kernelspec loading...
r19886 that.set_kernel(data.kernel.name);
Thomas Kluyver
Don't refer to global kernelselector object in Session
r17384 });
Thomas Kluyver
Hide kernel logo if it's missing
r19374
Min RK
load kernel js, css, logo on spec_changed event...
r19745 var logo_img = this.element.find("img.current_kernel_logo");
Thomas Kluyver
Hide kernel logo if it's missing
r19374 logo_img.on("load", function() {
logo_img.show();
});
logo_img.on("error", function() {
logo_img.hide();
});
Thomas Kluyver
Change displayed kernel name when our session is started
r17371 };
Thomas Kluyver
Allow switching kernel from the notebook UI
r17370 return {'KernelSelector': KernelSelector};
});