notebook/IPython/html/static/base/js/dialog.js

213 lines
7.2 KiB
JavaScript
Raw Normal View History

// Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.
2013-06-03 06:44:23 +08:00
define(function(require) {
"use strict";
var CodeMirror = require('codemirror/lib/codemirror');
var IPython = require('base/js/namespace');
var $ = require('jquery');
2013-06-03 06:44:23 +08:00
/**
* A wrapper around bootstrap modal for easier use
* Pass it an option dictionary with the following properties:
*
* - body : <string> or <DOM node>, main content of the dialog
* if pass a <string> it will be wrapped in a p tag and
* html element escaped, unless you specify sanitize=false
* option.
* - title : Dialog title, default to empty string.
* - buttons : dict of btn_options who keys are button label.
* see btn_options below for description
* - open : callback to trigger on dialog open.
* - destroy:
* - notebook : notebook instance
* - keyboard_manager: keyboard manager instance.
*
* Unlike bootstrap modals, the backdrop options is set by default
* to 'static'.
*
* The rest of the options are passed as is to bootstrap modals.
*
* btn_options: dict with the following property:
*
* - click : callback to trigger on click
* - class : css classes to add to button.
*
*
*
**/
2014-06-27 01:45:33 +08:00
var modal = function (options) {
2014-04-18 07:05:35 +08:00
var modal = $("<div/>")
.addClass("modal")
.addClass("fade")
.attr("role", "dialog");
var dialog = $("<div/>")
.addClass("modal-dialog")
.appendTo(modal);
var dialog_content = $("<div/>")
.addClass("modal-content")
.appendTo(dialog);
if(typeof(options.body) === 'string' && options.sanitize !== false){
options.body = $("<p/>").text(options.body)
}
2014-04-18 07:05:35 +08:00
dialog_content.append(
2013-06-03 06:44:23 +08:00
$("<div/>")
.addClass("modal-header")
.append($("<button>")
2014-04-18 07:05:35 +08:00
.attr("type", "button")
2013-06-03 06:44:23 +08:00
.addClass("close")
.attr("data-dismiss", "modal")
2014-04-18 07:05:35 +08:00
.attr("aria-hidden", "true")
2013-06-03 06:44:23 +08:00
.html("&times;")
).append(
2014-04-18 07:05:35 +08:00
$("<h4/>")
.addClass('modal-title')
.text(options.title || "")
2013-06-03 06:44:23 +08:00
)
).append(
$("<div/>").addClass("modal-body").append(
options.body || $("<p/>")
)
);
var footer = $("<div/>").addClass("modal-footer");
for (var label in options.buttons) {
var btn_opts = options.buttons[label];
var button = $("<button/>")
2014-06-10 07:13:59 +08:00
.addClass("btn btn-default btn-sm")
2013-06-03 06:44:23 +08:00
.attr("data-dismiss", "modal")
.text(label);
if (btn_opts.click) {
2014-04-18 07:05:35 +08:00
button.click($.proxy(btn_opts.click, dialog_content));
2013-06-03 06:44:23 +08:00
}
if (btn_opts.class) {
button.addClass(btn_opts.class);
}
footer.append(button);
}
2014-04-18 07:05:35 +08:00
dialog_content.append(footer);
2013-06-03 06:44:23 +08:00
// hook up on-open event
2014-05-23 05:29:50 +08:00
modal.on("shown.bs.modal", function() {
2013-06-03 06:44:23 +08:00
setTimeout(function() {
footer.find("button").last().focus();
if (options.open) {
2014-04-18 07:05:35 +08:00
$.proxy(options.open, modal)();
2013-06-03 06:44:23 +08:00
}
}, 0);
});
2014-04-18 07:05:35 +08:00
// destroy modal on hide, unless explicitly asked not to
2013-10-03 06:26:19 +08:00
if (options.destroy === undefined || options.destroy) {
2014-05-23 05:29:50 +08:00
modal.on("hidden.bs.modal", function () {
2014-04-18 07:05:35 +08:00
modal.remove();
2013-06-03 06:44:23 +08:00
});
}
2014-05-23 05:29:50 +08:00
modal.on("hidden.bs.modal", function () {
2014-06-27 01:45:33 +08:00
if (options.notebook) {
var cell = options.notebook.get_selected_cell();
if (cell) cell.select();
}
if (options.keyboard_manager) {
options.keyboard_manager.enable();
options.keyboard_manager.command_mode();
}
});
2014-06-27 01:45:33 +08:00
if (options.keyboard_manager) {
options.keyboard_manager.disable();
}
options.backdrop = options.backdrop || 'static';
2013-06-03 06:44:23 +08:00
2014-04-18 07:05:35 +08:00
return modal.modal(options);
2013-10-03 06:26:19 +08:00
};
var kernel_modal = function (options) {
2014-12-04 05:42:43 +08:00
/**
* only one kernel dialog should be open at a time -- but
* other modal dialogs can still be open
*/
$('.kernel-modal').modal('hide');
var dialog = modal(options);
dialog.addClass('kernel-modal');
return dialog;
};
2014-07-02 03:04:27 +08:00
var edit_metadata = function (options) {
options.name = options.name || "Cell";
2013-10-03 06:26:19 +08:00
var error_div = $('<div/>').css('color', 'red');
var message =
2014-07-02 03:04:27 +08:00
"Manually edit the JSON below to manipulate the metadata for this " + options.name + "." +
2013-10-03 06:26:19 +08:00
" We recommend putting custom metadata attributes in an appropriately named sub-structure," +
" so they don't conflict with those of others.";
var textarea = $('<textarea/>')
.attr('rows', '13')
.attr('cols', '80')
.attr('name', 'metadata')
2014-07-02 03:04:27 +08:00
.text(JSON.stringify(options.md || {}, null, 2));
2013-10-03 06:26:19 +08:00
var dialogform = $('<div/>').attr('title', 'Edit the metadata')
.append(
$('<form/>').append(
$('<fieldset/>').append(
$('<label/>')
.attr('for','metadata')
.text(message)
)
.append(error_div)
.append($('<br/>'))
.append(textarea)
)
);
var editor = CodeMirror.fromTextArea(textarea[0], {
lineNumbers: true,
matchBrackets: true,
indentUnit: 2,
autoIndent: true,
mode: 'application/json',
});
var modal_obj = modal({
2014-07-02 03:04:27 +08:00
title: "Edit " + options.name + " Metadata",
2013-10-03 06:26:19 +08:00
body: dialogform,
buttons: {
OK: { class : "btn-primary",
click: function() {
2014-12-04 05:42:43 +08:00
/**
* validate json and set it
*/
2013-10-03 06:26:19 +08:00
var new_md;
try {
new_md = JSON.parse(editor.getValue());
} catch(e) {
console.log(e);
error_div.text('WARNING: Could not save invalid JSON.');
return false;
}
2014-07-02 03:04:27 +08:00
options.callback(new_md);
2013-10-03 06:26:19 +08:00
}
},
Cancel: {}
2014-07-02 03:04:27 +08:00
},
notebook: options.notebook,
keyboard_manager: options.keyboard_manager,
});
2014-06-07 07:32:10 +08:00
modal_obj.on('shown.bs.modal', function(){ editor.refresh(); });
2013-10-03 06:26:19 +08:00
};
2013-06-03 06:44:23 +08:00
2014-06-24 01:56:37 +08:00
var dialog = {
2013-06-03 06:44:23 +08:00
modal : modal,
kernel_modal : kernel_modal,
2013-10-03 06:26:19 +08:00
edit_metadata : edit_metadata,
2013-06-03 06:44:23 +08:00
};
// Backwards compatability.
2014-07-02 03:04:27 +08:00
IPython.dialog = dialog;
2014-06-24 01:56:37 +08:00
return dialog;
});