mirror of
https://github.com/jupyter/notebook.git
synced 2025-02-05 12:19:58 +08:00
Merge pull request #6544 from jhamrick/notification-widget
Clean up notification widget
This commit is contained in:
commit
2d490858e5
@ -11,16 +11,22 @@ define([
|
||||
], function(IPython, $, utils, dialog, notificationwidget, moment) {
|
||||
"use strict";
|
||||
|
||||
// store reference to the NotificationWidget class
|
||||
var NotificationWidget = notificationwidget.NotificationWidget;
|
||||
|
||||
/**
|
||||
* Construct the NotificationArea object. Options are:
|
||||
* events: $(Events) instance
|
||||
* save_widget: SaveWidget instance
|
||||
* notebook: Notebook instance
|
||||
* keyboard_manager: KeyboardManager instance
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} selector - a jQuery selector string for the
|
||||
* notification area element
|
||||
* @param {Object} [options] - a dictionary of keyword arguments.
|
||||
*/
|
||||
var NotificationArea = function (selector, options) {
|
||||
// Constructor
|
||||
//
|
||||
// Parameters:
|
||||
// selector: string
|
||||
// options: dictionary
|
||||
// Dictionary of keyword arguments.
|
||||
// notebook: Notebook instance
|
||||
// events: $(Events) instance
|
||||
// save_widget: SaveWidget instance
|
||||
this.selector = selector;
|
||||
this.events = options.events;
|
||||
this.save_widget = options.save_widget;
|
||||
@ -32,47 +38,70 @@ define([
|
||||
this.widget_dict = {};
|
||||
};
|
||||
|
||||
NotificationArea.prototype.temp_message = function (msg, timeout, css_class) {
|
||||
var tdiv = $('<div>')
|
||||
.addClass('notification_widget')
|
||||
.addClass(css_class)
|
||||
.hide()
|
||||
.text(msg);
|
||||
|
||||
$(this.selector).append(tdiv);
|
||||
var tmout = Math.max(1500,(timeout||1500));
|
||||
tdiv.fadeIn(100);
|
||||
|
||||
setTimeout(function () {
|
||||
tdiv.fadeOut(100, function () {tdiv.remove();});
|
||||
}, tmout);
|
||||
};
|
||||
|
||||
NotificationArea.prototype.widget = function(name) {
|
||||
if(this.widget_dict[name] === undefined) {
|
||||
/**
|
||||
* Get a widget by name, creating it if it doesn't exist.
|
||||
*
|
||||
* @method widget
|
||||
* @param {string} name - the widget name
|
||||
*/
|
||||
NotificationArea.prototype.widget = function (name) {
|
||||
if (this.widget_dict[name] === undefined) {
|
||||
return this.new_notification_widget(name);
|
||||
}
|
||||
return this.get_widget(name);
|
||||
};
|
||||
|
||||
NotificationArea.prototype.get_widget = function(name) {
|
||||
/**
|
||||
* Get a widget by name, throwing an error if it doesn't exist.
|
||||
*
|
||||
* @method get_widget
|
||||
* @param {string} name - the widget name
|
||||
*/
|
||||
NotificationArea.prototype.get_widget = function (name) {
|
||||
if(this.widget_dict[name] === undefined) {
|
||||
throw('no widgets with this name');
|
||||
}
|
||||
return this.widget_dict[name];
|
||||
};
|
||||
|
||||
NotificationArea.prototype.new_notification_widget = function(name) {
|
||||
if(this.widget_dict[name] !== undefined) {
|
||||
throw('widget with that name already exists ! ');
|
||||
/**
|
||||
* Create a new notification widget with the given name. The
|
||||
* widget must not already exist.
|
||||
*
|
||||
* @method new_notification_widget
|
||||
* @param {string} name - the widget name
|
||||
*/
|
||||
NotificationArea.prototype.new_notification_widget = function (name) {
|
||||
if (this.widget_dict[name] !== undefined) {
|
||||
throw('widget with that name already exists!');
|
||||
}
|
||||
var div = $('<div/>').attr('id','notification_'+name);
|
||||
|
||||
// create the element for the notification widget and add it
|
||||
// to the notification aread element
|
||||
var div = $('<div/>').attr('id', 'notification_' + name);
|
||||
$(this.selector).append(div);
|
||||
this.widget_dict[name] = new notificationwidget.NotificationWidget('#notification_'+name);
|
||||
|
||||
// create the widget object and return it
|
||||
this.widget_dict[name] = new NotificationWidget('#notification_' + name);
|
||||
return this.widget_dict[name];
|
||||
};
|
||||
|
||||
NotificationArea.prototype.init_notification_widgets = function() {
|
||||
/**
|
||||
* Initialize the default set of notification widgets.
|
||||
*
|
||||
* @method init_notification_widgets
|
||||
*/
|
||||
NotificationArea.prototype.init_notification_widgets = function () {
|
||||
this.init_kernel_notification_widget();
|
||||
this.init_notebook_notification_widget();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the notification widget for kernel status messages.
|
||||
*
|
||||
* @method init_kernel_notification_widget
|
||||
*/
|
||||
NotificationArea.prototype.init_kernel_notification_widget = function () {
|
||||
var that = this;
|
||||
var knw = this.new_notification_widget('kernel');
|
||||
var $kernel_ind_icon = $("#kernel_indicator_icon");
|
||||
@ -194,8 +223,14 @@ define([
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the notification widget for notebook status messages.
|
||||
*
|
||||
* @method init_notebook_notification_widget
|
||||
*/
|
||||
NotificationArea.prototype.init_notebook_notification_widget = function () {
|
||||
var nnw = this.new_notification_widget('notebook');
|
||||
|
||||
// Notebook events
|
||||
@ -247,7 +282,6 @@ define([
|
||||
this.events.on('autosave_enabled.Notebook', function (evt, interval) {
|
||||
nnw.set_message("Saving every " + interval / 1000 + "s", 1000);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
IPython.NotificationArea = NotificationArea;
|
||||
|
@ -7,6 +7,13 @@ define([
|
||||
], function(IPython, $) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Construct a NotificationWidget object.
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} selector - a jQuery selector string for the
|
||||
* notification widget element
|
||||
*/
|
||||
var NotificationWidget = function (selector) {
|
||||
this.selector = selector;
|
||||
this.timeout = null;
|
||||
@ -16,27 +23,41 @@ define([
|
||||
this.style();
|
||||
}
|
||||
this.element.hide();
|
||||
var that = this;
|
||||
|
||||
this.inner = $('<span/>');
|
||||
this.element.append(this.inner);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the 'notification_widget' CSS class to the widget element.
|
||||
*
|
||||
* @method style
|
||||
*/
|
||||
NotificationWidget.prototype.style = function () {
|
||||
this.element.addClass('notification_widget');
|
||||
};
|
||||
|
||||
// msg : message to display
|
||||
// timeout : time in ms before diseapearing
|
||||
//
|
||||
// if timeout <= 0
|
||||
// click_callback : function called if user click on notification
|
||||
// could return false to prevent the notification to be dismissed
|
||||
/**
|
||||
* Set the notification widget message to display for a certain
|
||||
* amount of time (timeout). The widget will be shown forever if
|
||||
* timeout is <= 0 or undefined. If the widget is clicked while it
|
||||
* is still displayed, execute an optional callback
|
||||
* (click_callback). If the callback returns false, it will
|
||||
* prevent the notification from being dismissed.
|
||||
*
|
||||
* Options:
|
||||
* class - CSS class name for styling
|
||||
* icon - CSS class name for the widget icon
|
||||
* title - HTML title attribute for the widget
|
||||
*
|
||||
* @method set_message
|
||||
* @param {string} msg - The notification to display
|
||||
* @param {integer} [timeout] - The amount of time in milliseconds to display the widget
|
||||
* @param {function} [click_callback] - The function to run when the widget is clicked
|
||||
* @param {Object} [options] - Additional options
|
||||
*/
|
||||
NotificationWidget.prototype.set_message = function (msg, timeout, click_callback, options) {
|
||||
var options = options || {};
|
||||
var callback = click_callback || function() {return true;};
|
||||
var that = this;
|
||||
options = options || {};
|
||||
|
||||
// unbind potential previous callback
|
||||
this.element.unbind('click');
|
||||
this.inner.attr('class', options.icon);
|
||||
@ -47,52 +68,87 @@ define([
|
||||
// reset previous set style
|
||||
this.element.removeClass();
|
||||
this.style();
|
||||
if (options.class){
|
||||
|
||||
this.element.addClass(options.class)
|
||||
if (options.class) {
|
||||
this.element.addClass(options.class);
|
||||
}
|
||||
|
||||
// clear previous timer
|
||||
if (this.timeout !== null) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
if (timeout !== undefined && timeout >=0) {
|
||||
|
||||
// set the timer if a timeout is given
|
||||
var that = this;
|
||||
if (timeout !== undefined && timeout >= 0) {
|
||||
this.timeout = setTimeout(function () {
|
||||
that.element.fadeOut(100, function () {that.inner.text('');});
|
||||
that.element.unbind('click');
|
||||
that.timeout = null;
|
||||
}, timeout);
|
||||
} else {
|
||||
this.element.click(function() {
|
||||
if( callback() !== false ) {
|
||||
}
|
||||
|
||||
// bind the click callback if it is given
|
||||
if (click_callback !== undefined) {
|
||||
this.element.click(function () {
|
||||
if (click_callback() !== false) {
|
||||
that.element.fadeOut(100, function () {that.inner.text('');});
|
||||
that.element.unbind('click');
|
||||
}
|
||||
if (that.timeout !== undefined) {
|
||||
that.timeout = undefined;
|
||||
that.element.unbind('click');
|
||||
if (that.timeout !== null) {
|
||||
clearTimeout(that.timeout);
|
||||
that.timeout = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Display an information message (styled with the 'info'
|
||||
* class). Arguments are the same as in set_message. Default
|
||||
* timeout is 3500 milliseconds.
|
||||
*
|
||||
* @method info
|
||||
*/
|
||||
NotificationWidget.prototype.info = function (msg, timeout, click_callback, options) {
|
||||
var options = options || {};
|
||||
options.class = options.class +' info';
|
||||
var timeout = timeout || 3500;
|
||||
options = options || {};
|
||||
options.class = options.class + ' info';
|
||||
timeout = timeout || 3500;
|
||||
this.set_message(msg, timeout, click_callback, options);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a warning message (styled with the 'warning'
|
||||
* class). Arguments are the same as in set_message. Messages are
|
||||
* sticky by default.
|
||||
*
|
||||
* @method warning
|
||||
*/
|
||||
NotificationWidget.prototype.warning = function (msg, timeout, click_callback, options) {
|
||||
var options = options || {};
|
||||
options.class = options.class +' warning';
|
||||
options = options || {};
|
||||
options.class = options.class + ' warning';
|
||||
this.set_message(msg, timeout, click_callback, options);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a danger message (styled with the 'danger'
|
||||
* class). Arguments are the same as in set_message. Messages are
|
||||
* sticky by default.
|
||||
*
|
||||
* @method danger
|
||||
*/
|
||||
NotificationWidget.prototype.danger = function (msg, timeout, click_callback, options) {
|
||||
var options = options || {};
|
||||
options.class = options.class +' danger';
|
||||
options = options || {};
|
||||
options.class = options.class + ' danger';
|
||||
this.set_message(msg, timeout, click_callback, options);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text of the widget message.
|
||||
*
|
||||
* @method get_message
|
||||
* @return {string} - the message text
|
||||
*/
|
||||
NotificationWidget.prototype.get_message = function () {
|
||||
return this.inner.html();
|
||||
};
|
||||
|
116
IPython/html/tests/notebook/notifications.js
Normal file
116
IPython/html/tests/notebook/notifications.js
Normal file
@ -0,0 +1,116 @@
|
||||
// Test the notification area and widgets
|
||||
|
||||
casper.notebook_test(function () {
|
||||
var that = this;
|
||||
var widget = function (name) {
|
||||
return that.evaluate(function (name) {
|
||||
return (IPython.notification_area.widget(name) !== undefined);
|
||||
}, name);
|
||||
};
|
||||
|
||||
var get_widget = function (name) {
|
||||
return that.evaluate(function (name) {
|
||||
return (IPython.notification_area.get_widget(name) !== undefined);
|
||||
}, name);
|
||||
};
|
||||
|
||||
var new_notification_widget = function (name) {
|
||||
return that.evaluate(function (name) {
|
||||
return (IPython.notification_area.new_notification_widget(name) !== undefined);
|
||||
}, name);
|
||||
};
|
||||
|
||||
var widget_has_class = function (name, class_name) {
|
||||
return that.evaluate(function (name, class_name) {
|
||||
var w = IPython.notification_area.get_widget(name);
|
||||
return w.element.hasClass(class_name);
|
||||
}, name, class_name);
|
||||
};
|
||||
|
||||
var widget_message = function (name) {
|
||||
return that.evaluate(function (name) {
|
||||
var w = IPython.notification_area.get_widget(name);
|
||||
return w.get_message();
|
||||
}, name);
|
||||
};
|
||||
|
||||
this.then(function () {
|
||||
// check that existing widgets are there
|
||||
this.test.assert(get_widget('kernel') && widget('kernel'), 'The kernel notification widget exists');
|
||||
this.test.assert(get_widget('notebook') && widget('notbook'), 'The notebook notification widget exists');
|
||||
|
||||
// try getting a non-existant widget
|
||||
this.test.assertRaises(get_widget, 'foo', 'get_widget: error is thrown');
|
||||
|
||||
// try creating a non-existant widget
|
||||
this.test.assert(widget('bar'), 'widget: new widget is created');
|
||||
|
||||
// try creating a widget that already exists
|
||||
this.test.assertRaises(new_notification_widget, 'kernel', 'new_notification_widget: error is thrown');
|
||||
});
|
||||
|
||||
// test creating 'info' messages
|
||||
this.thenEvaluate(function () {
|
||||
var tnw = IPython.notification_area.widget('test');
|
||||
tnw.info('test info');
|
||||
});
|
||||
this.waitUntilVisible('#notification_test', function () {
|
||||
this.test.assert(widget_has_class('test', 'info'), 'info: class is correct');
|
||||
this.test.assertEquals(widget_message('test'), 'test info', 'info: message is correct');
|
||||
});
|
||||
|
||||
// test creating 'warning' messages
|
||||
this.thenEvaluate(function () {
|
||||
var tnw = IPython.notification_area.widget('test');
|
||||
tnw.warning('test warning');
|
||||
});
|
||||
this.waitUntilVisible('#notification_test', function () {
|
||||
this.test.assert(widget_has_class('test', 'warning'), 'warning: class is correct');
|
||||
this.test.assertEquals(widget_message('test'), 'test warning', 'warning: message is correct');
|
||||
});
|
||||
|
||||
// test creating 'danger' messages
|
||||
this.thenEvaluate(function () {
|
||||
var tnw = IPython.notification_area.widget('test');
|
||||
tnw.danger('test danger');
|
||||
});
|
||||
this.waitUntilVisible('#notification_test', function () {
|
||||
this.test.assert(widget_has_class('test', 'danger'), 'danger: class is correct');
|
||||
this.test.assertEquals(widget_message('test'), 'test danger', 'danger: message is correct');
|
||||
});
|
||||
|
||||
// test message timeout
|
||||
this.thenEvaluate(function () {
|
||||
var tnw = IPython.notification_area.widget('test');
|
||||
tnw.set_message('test timeout', 1000);
|
||||
});
|
||||
this.waitUntilVisible('#notification_test', function () {
|
||||
this.test.assertEquals(widget_message('test'), 'test timeout', 'timeout: message is correct');
|
||||
});
|
||||
this.waitWhileVisible('#notification_test', function () {
|
||||
this.test.assertEquals(widget_message('test'), '', 'timeout: message was cleared');
|
||||
});
|
||||
|
||||
// test click callback
|
||||
this.thenEvaluate(function () {
|
||||
var tnw = IPython.notification_area.widget('test');
|
||||
tnw._clicked = false;
|
||||
tnw.set_message('test click', undefined, function () {
|
||||
tnw._clicked = true;
|
||||
return true;
|
||||
});
|
||||
});
|
||||
this.waitUntilVisible('#notification_test', function () {
|
||||
this.test.assertEquals(widget_message('test'), 'test click', 'callback: message is correct');
|
||||
this.click('#notification_test');
|
||||
});
|
||||
this.waitFor(function () {
|
||||
return this.evaluate(function () {
|
||||
return IPython.notification_area.widget('test')._clicked;
|
||||
});
|
||||
}, function () {
|
||||
this.waitWhileVisible('#notification_test', function () {
|
||||
this.test.assertEquals(widget_message('test'), '', 'callback: message was cleared');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user