From ed25637875ccb25cddd26998c58740deb5eeede1 2012-02-01 05:42:01 From: Brian Granger <ellisonbg@gmail.com> Date: 2012-02-01 05:42:01 Subject: [PATCH] Major refactoring of saving, notification. * Refactored the save widget so that the notebook doesn't depend on it. Now the notebook emits events and the save widget observes those events. * Created a new event system for all IPython events (events.js). We should start to use this to allow our classes to be loosely coupled. * Created a new notification widget that should be used for all notifications. Uses new event system. * Removed the kernel status widget. * All kernel status message use new event/notification system. * The print notebook view works again. --- diff --git a/IPython/frontend/html/notebook/static/css/notebook.css b/IPython/frontend/html/notebook/static/css/notebook.css index 73bc5be..6fa3ab9 100644 --- a/IPython/frontend/html/notebook/static/css/notebook.css +++ b/IPython/frontend/html/notebook/static/css/notebook.css @@ -55,6 +55,19 @@ span#notebook_name { margin: 0.3em 0; } +#menubar_container { + position: relative; +} + +#notification { + position: absolute; + right: 3px; + top: 3px; + height: 25px; + padding: 3px 6px; + z-index: 10; +} + #toolbar { /* Initially hidden to prevent FLOUC */ display: none; @@ -71,31 +84,6 @@ span#quick_help_area { margin: 0px 0px 0px 0px; } -span#kernel_status { - position: absolute; - padding: 8px 5px 5px 5px; - right: 10px; - font-weight: bold; -} - - -.status_idle { - color: gray; - visibility: hidden; -} - -.status_busy { - color: red; -} - -.status_restarting { - color: black; -} - -#kernel_persist { - float: right; -} - .help_string { float: right; width: 170px; diff --git a/IPython/frontend/html/notebook/static/js/events.js b/IPython/frontend/html/notebook/static/js/events.js new file mode 100644 index 0000000..0ff950d --- /dev/null +++ b/IPython/frontend/html/notebook/static/js/events.js @@ -0,0 +1,31 @@ +//---------------------------------------------------------------------------- +// Copyright (C) 2008-2011 The IPython Development Team +// +// Distributed under the terms of the BSD License. The full license is in +// the file COPYING, distributed as part of this software. +//---------------------------------------------------------------------------- + +//============================================================================ +// Events +//============================================================================ + +// Give us an object to bind all events to. This object should be created +// before all other objects so it exists when others register event handlers. +// To trigger an event handler: +// $([IPython.events]).trigger('event.Namespace); +// To handle it: +// $([IPython.events]).on('event.Namespace',function () {}); + +var IPython = (function (IPython) { + + var utils = IPython.utils; + + var Events = function () {}; + + IPython.Events = Events; + IPython.events = new Events(); + + return IPython; + +}(IPython)); + diff --git a/IPython/frontend/html/notebook/static/js/kernel.js b/IPython/frontend/html/notebook/static/js/kernel.js index 6f00922..68e486a 100644 --- a/IPython/frontend/html/notebook/static/js/kernel.js +++ b/IPython/frontend/html/notebook/static/js/kernel.js @@ -62,7 +62,7 @@ var IPython = (function (IPython) { Kernel.prototype.restart = function (callback) { - IPython.kernel_status_widget.status_restarting(); + $([IPython.events]).trigger('status_restarting.Kernel'); var url = this.kernel_url + "/restart"; var that = this; if (this.running) { @@ -84,20 +84,19 @@ var IPython = (function (IPython) { this.kernel_url = this.base_url + "/" + this.kernel_id; this.start_channels(); callback(); - IPython.kernel_status_widget.status_idle(); }; Kernel.prototype._websocket_closed = function(ws_url, early){ var msg; var parent_item = $('body'); if (early) { - msg = "Websocket connection to " + ws_url + " could not be established.<br/>" + - " You will NOT be able to run code.<br/>" + + msg = "Websocket connection to " + ws_url + " could not be established." + + " You will NOT be able to run code." + " Your browser may not be compatible with the websocket version in the server," + " or if the url does not look right, there could be an error in the" + " server's configuration."; } else { - msg = "Websocket connection closed unexpectedly.<br/>" + + msg = "Websocket connection closed unexpectedly." + " The kernel will no longer be responsive."; } var dialog = $('<div/>'); @@ -211,6 +210,7 @@ var IPython = (function (IPython) { Kernel.prototype.interrupt = function () { if (this.running) { + $([IPython.events]).trigger('status_interrupting.Kernel'); $.post(this.kernel_url + "/interrupt"); }; }; diff --git a/IPython/frontend/html/notebook/static/js/kernelstatus.js b/IPython/frontend/html/notebook/static/js/kernelstatus.js deleted file mode 100644 index 5b61157..0000000 --- a/IPython/frontend/html/notebook/static/js/kernelstatus.js +++ /dev/null @@ -1,65 +0,0 @@ -//---------------------------------------------------------------------------- -// Copyright (C) 2008-2011 The IPython Development Team -// -// Distributed under the terms of the BSD License. The full license is in -// the file COPYING, distributed as part of this software. -//---------------------------------------------------------------------------- - -//============================================================================ -// Kernel Status widget -//============================================================================ - -var IPython = (function (IPython) { - - var utils = IPython.utils; - - var KernelStatusWidget = function (selector) { - this.selector = selector; - if (this.selector !== undefined) { - this.element = $(selector); - this.style(); - } - }; - - - KernelStatusWidget.prototype.style = function () { - this.element.addClass('ui-widget'); - this.element.attr('title', "The kernel execution status." + - " If 'Busy', the kernel is currently running code." + - " If 'Idle', it is available for execution."); - }; - - - KernelStatusWidget.prototype.status_busy = function () { - this.element.removeClass("status_idle"); - this.element.removeClass("status_restarting"); - this.element.addClass("status_busy"); - window.document.title='(Busy) '+window.document.title; - this.element.text("Busy"); - }; - - - KernelStatusWidget.prototype.status_idle = function () { - this.element.removeClass("status_busy"); - this.element.removeClass("status_restarting"); - this.element.addClass("status_idle"); - IPython.save_widget.set_document_title(); - this.element.text("Idle"); - }; - - KernelStatusWidget.prototype.status_restarting = function () { - this.element.removeClass("status_busy"); - this.element.removeClass("status_idle"); - this.element.addClass("status_restarting"); - this.element.text("Restarting"); - }; - - - - - IPython.KernelStatusWidget = KernelStatusWidget; - - return IPython; - -}(IPython)); - diff --git a/IPython/frontend/html/notebook/static/js/menubar.js b/IPython/frontend/html/notebook/static/js/menubar.js index b513ecd..eef2e44 100644 --- a/IPython/frontend/html/notebook/static/js/menubar.js +++ b/IPython/frontend/html/notebook/static/js/menubar.js @@ -45,21 +45,21 @@ var IPython = (function (IPython) { IPython.save_widget.rename_notebook(); }); this.element.find('#copy_notebook').click(function () { - var notebook_id = IPython.save_widget.get_notebook_id(); + var notebook_id = IPython.notebook.get_notebook_id(); var url = $('body').data('baseProjectUrl') + notebook_id + '/copy'; window.open(url,'_newtab'); }); this.element.find('#save_notebook').click(function () { - IPython.save_widget.save_notebook(); + IPython.notebook.save_notebook(); }); this.element.find('#download_ipynb').click(function () { - var notebook_id = IPython.save_widget.get_notebook_id(); + var notebook_id = IPython.notebook.get_notebook_id(); var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id + '?format=json'; window.open(url,'_newtab'); }); this.element.find('#download_py').click(function () { - var notebook_id = IPython.save_widget.get_notebook_id(); + var notebook_id = IPython.notebook.get_notebook_id(); var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id + '?format=py'; window.open(url,'_newtab'); diff --git a/IPython/frontend/html/notebook/static/js/notebook.js b/IPython/frontend/html/notebook/static/js/notebook.js index df20219..02221a0 100644 --- a/IPython/frontend/html/notebook/static/js/notebook.js +++ b/IPython/frontend/html/notebook/static/js/notebook.js @@ -26,6 +26,9 @@ var IPython = (function (IPython) { this.msg_cell_map = {}; this.metadata = {}; this.control_key_active = false; + this.notebook_id = null; + this.notebook_name = null; + this.notebook_name_blacklist_re = /[\/\\]/; this.style(); this.create_elements(); this.bind_events(); @@ -66,7 +69,7 @@ var IPython = (function (IPython) { // Save (CTRL+S) or (AppleKey+S) //metaKey = applekey on mac if ((event.ctrlKey || event.metaKey) && event.keyCode==83) { - IPython.save_widget.save_notebook(); + that.save_notebook(); event.preventDefault(); return false; } else if (event.which === 27) { @@ -177,7 +180,7 @@ var IPython = (function (IPython) { return false; } else if (event.which === 83 && that.control_key_active) { // Save notebook = s - IPython.save_widget.save_notebook(); + that.save_notebook(); that.control_key_active = false; return false; } else if (event.which === 74 && that.control_key_active) { @@ -207,12 +210,12 @@ var IPython = (function (IPython) { return false; } else if (event.which === 73 && that.control_key_active) { // Interrupt kernel = i - IPython.notebook.kernel.interrupt(); + that.kernel.interrupt(); that.control_key_active = false; return false; } else if (event.which === 190 && that.control_key_active) { // Restart kernel = . # matches qt console - IPython.notebook.restart_kernel(); + that.restart_kernel(); that.control_key_active = false; return false; } else if (event.which === 72 && that.control_key_active) { @@ -402,10 +405,14 @@ var IPython = (function (IPython) { var cell = this.get_cell(index) cell.select(); if (cell.cell_type === 'heading') { - IPython.toolbar.set_cell_type(cell.cell_type+cell.level); + $([IPython.events]).trigger('selected_cell_type_changed.Notebook', + {'cell_type':cell.cell_type,level:cell.level} + ); } else { - IPython.toolbar.set_cell_type(cell.cell_type) - } + $([IPython.events]).trigger('selected_cell_type_changed.Notebook', + {'cell_type':cell.cell_type} + ); + }; }; return this; }; @@ -676,7 +683,9 @@ var IPython = (function (IPython) { source_element.remove(); this.dirty = true; }; - IPython.toolbar.set_cell_type("heading"+level); + $([IPython.events]).trigger('selected_cell_type_changed.Notebook', + {'cell_type':'heading',level:level} + ); }; }; @@ -880,15 +889,12 @@ var IPython = (function (IPython) { Notebook.prototype.start_kernel = function () { this.kernel = new IPython.Kernel(); - var notebook_id = IPython.save_widget.get_notebook_id(); - this.kernel.start(notebook_id, $.proxy(this.kernel_started, this)); + this.kernel.start(this.notebook_id, $.proxy(this.kernel_started, this)); }; Notebook.prototype.restart_kernel = function () { var that = this; - var notebook_id = IPython.save_widget.get_notebook_id(); - var dialog = $('<div/>'); dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.'); $(document).append(dialog); @@ -976,8 +982,8 @@ var IPython = (function (IPython) { var cell = this.cell_for_msg(reply.parent_header.msg_id); if (msg_type !== 'status' && !cell){ // message not from this notebook, but should be attached to a cell - console.log("Received IOPub message not caused by one of my cells"); - console.log(reply); + // console.log("Received IOPub message not caused by one of my cells"); + // console.log(reply); return; } var output_types = ['stream','display_data','pyout','pyerr']; @@ -985,9 +991,10 @@ var IPython = (function (IPython) { this.handle_output(cell, msg_type, content); } else if (msg_type === 'status') { if (content.execution_state === 'busy') { + $([IPython.events]).trigger('status_busy.Kernel'); IPython.kernel_status_widget.status_busy(); } else if (content.execution_state === 'idle') { - IPython.kernel_status_widget.status_idle(); + $([IPython.events]).trigger('status_idle.Kernel'); } else if (content.execution_state === 'dead') { this.handle_status_dead(); }; @@ -1142,8 +1149,33 @@ var IPython = (function (IPython) { this.msg_cell_map[msg_id] = cell.cell_id; }; + // Persistance and loading + Notebook.prototype.get_notebook_id = function () { + return this.notebook_id; + }; + + + Notebook.prototype.get_notebook_name = function () { + return this.notebook_name; + }; + + + Notebook.prototype.set_notebook_name = function (name) { + this.notebook_name = name; + }; + + + Notebook.prototype.test_notebook_name = function (nbname) { + nbname = nbname || ''; + if (this.notebook_name_blacklist_re.test(nbname) == false && nbname.length>0) { + return true; + } else { + return false; + }; + }; + Notebook.prototype.fromJSON = function (data) { var ncells = this.ncells(); @@ -1152,8 +1184,9 @@ var IPython = (function (IPython) { // Always delete cell 0 as they get renumbered as they are deleted. this.delete_cell(0); }; - // Save the metadata + // Save the metadata and name. this.metadata = data.metadata; + this.notebook_name = data.metadata.name; // Only handle 1 worksheet for now. var worksheet = data.worksheets[0]; if (worksheet !== undefined) { @@ -1186,11 +1219,9 @@ var IPython = (function (IPython) { }; Notebook.prototype.save_notebook = function () { - var notebook_id = IPython.save_widget.get_notebook_id(); - var nbname = IPython.save_widget.get_notebook_name(); // We may want to move the name/id/nbformat logic inside toJSON? var data = this.toJSON(); - data.metadata.name = nbname; + data.metadata.name = this.notebook_name; data.nbformat = 3; // We do the call with settings so we can set cache to false. var settings = { @@ -1199,30 +1230,29 @@ var IPython = (function (IPython) { type : "PUT", data : JSON.stringify(data), headers : {'Content-Type': 'application/json'}, - success : $.proxy(this.notebook_saved,this), + success : $.proxy(this.notebook_save_success,this), error : $.proxy(this.notebook_save_failed,this) }; - IPython.save_widget.status_saving(); - var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id; + $([IPython.events]).trigger('notebook_saving.Notebook'); + var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id; $.ajax(url, settings); }; - Notebook.prototype.notebook_saved = function (data, status, xhr) { + Notebook.prototype.notebook_save_success = function (data, status, xhr) { this.dirty = false; - IPython.save_widget.notebook_saved(); - IPython.save_widget.status_last_saved(); + $([IPython.events]).trigger('notebook_saved.Notebook'); }; Notebook.prototype.notebook_save_failed = function (xhr, status, error_msg) { - IPython.save_widget.status_save_failed(); + $([IPython.events]).trigger('notebook_save_failed.Notebook'); }; - Notebook.prototype.load_notebook = function () { + Notebook.prototype.load_notebook = function (notebook_id) { var that = this; - var notebook_id = IPython.save_widget.get_notebook_id(); + this.notebook_id = notebook_id; // We do the call with settings so we can set cache to false. var settings = { processData : false, @@ -1230,30 +1260,27 @@ var IPython = (function (IPython) { type : "GET", dataType : "json", success : function (data, status, xhr) { - that.notebook_loaded(data, status, xhr); + that.load_notebook_success(data, status, xhr); } }; - IPython.save_widget.status_loading(); - var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id; + $([IPython.events]).trigger('notebook_loading.Notebook'); + var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id; $.ajax(url, settings); }; - Notebook.prototype.notebook_loaded = function (data, status, xhr) { + Notebook.prototype.load_notebook_success = function (data, status, xhr) { this.fromJSON(data); if (this.ncells() === 0) { this.insert_cell_below('code'); }; - IPython.save_widget.status_last_saved(); - IPython.save_widget.set_notebook_name(data.metadata.name); this.dirty = false; if (! this.read_only) { this.start_kernel(); } this.select(0); this.scroll_to_top(); - IPython.save_widget.update_url(); - IPython.layout_manager.do_resize(); + $([IPython.events]).trigger('notebook_loaded.Notebook'); }; IPython.Notebook = Notebook; diff --git a/IPython/frontend/html/notebook/static/js/notebookmain.js b/IPython/frontend/html/notebook/static/js/notebookmain.js index bb5fd46..34cd61c 100644 --- a/IPython/frontend/html/notebook/static/js/notebookmain.js +++ b/IPython/frontend/html/notebook/static/js/notebookmain.js @@ -82,14 +82,13 @@ $(document).ready(function () { IPython.layout_manager = new IPython.LayoutManager(); IPython.pager = new IPython.Pager('div#pager', 'div#pager_splitter'); - IPython.save_widget = new IPython.SaveWidget('span#save_widget'); IPython.quick_help = new IPython.QuickHelp('span#quick_help_area'); IPython.login_widget = new IPython.LoginWidget('span#login_widget'); IPython.notebook = new IPython.Notebook('div#notebook'); - IPython.kernel_status_widget = new IPython.KernelStatusWidget('#kernel_status'); + IPython.save_widget = new IPython.SaveWidget('span#save_widget'); IPython.menubar = new IPython.MenuBar('#menubar') IPython.toolbar = new IPython.ToolBar('#toolbar') - IPython.kernel_status_widget.status_idle(); + IPython.notification_widget = new IPython.NotificationWidget('#notification') IPython.layout_manager.do_resize(); @@ -111,7 +110,11 @@ $(document).ready(function () { $('div#main_app').css('display','block'); IPython.layout_manager.do_resize(); - IPython.notebook.load_notebook(); + $([IPython.events]).on('notebook_loaded.Notebook', function () { + IPython.layout_manager.do_resize(); + IPython.save_widget.update_url(); + }) + IPython.notebook.load_notebook($('body').data('notebookId')); }); diff --git a/IPython/frontend/html/notebook/static/js/notificationwidget.js b/IPython/frontend/html/notebook/static/js/notificationwidget.js new file mode 100644 index 0000000..9147afc --- /dev/null +++ b/IPython/frontend/html/notebook/static/js/notificationwidget.js @@ -0,0 +1,102 @@ +//---------------------------------------------------------------------------- +// Copyright (C) 2008-2011 The IPython Development Team +// +// Distributed under the terms of the BSD License. The full license is in +// the file COPYING, distributed as part of this software. +//---------------------------------------------------------------------------- + +//============================================================================ +// Notification widget +//============================================================================ + +var IPython = (function (IPython) { + + var utils = IPython.utils; + + + var NotificationWidget = function (selector) { + this.selector = selector; + this.timeout = null; + this.busy = false; + if (this.selector !== undefined) { + this.element = $(selector); + this.style(); + this.bind_events(); + } + }; + + + NotificationWidget.prototype.style = function () { + this.element.addClass('ui-widget ui-widget-content ui-corner-all'); + this.element.addClass('border-box-sizing'); + }; + + + NotificationWidget.prototype.bind_events = function () { + var that = this; + // Kernel events + $([IPython.events]).on('status_idle.Kernel',function () { + IPython.save_widget.update_document_title(); + if (that.get_message() === 'Kernel busy') { + that.element.fadeOut(100, function () { + that.element.html(''); + }); + }; + }); + $([IPython.events]).on('status_busy.Kernel',function () { + window.document.title='(Busy) '+window.document.title; + that.set_message("Kernel busy"); + }); + $([IPython.events]).on('status_restarting.Kernel',function () { + that.set_message("Restarting kernel",500); + }); + $([IPython.events]).on('status_interrupting.Kernel',function () { + that.set_message("Interrupting kernel",500); + }); + // Notebook events + $([IPython.events]).on('notebook_loading.Notebook', function () { + that.set_message("Loading notebook",500); + }); + $([IPython.events]).on('notebook_loaded.Notebook', function () { + that.set_message("Notebook loaded",500); + }); + $([IPython.events]).on('notebook_saving.Notebook', function () { + that.set_message("Saving notebook",500); + }); + $([IPython.events]).on('notebook_saved.Notebook', function () { + that.set_message("Notebook saved",500); + }); + $([IPython.events]).on('notebook_save_failed.Notebook', function () { + that.set_message("Notebook save failed",500); + }); + }; + + + NotificationWidget.prototype.set_message = function (msg, timeout) { + var that = this; + this.element.html(msg); + this.element.fadeIn(100); + if (this.timeout !== null) { + clearTimeout(this.timeout); + this.timeout = null; + }; + if (timeout !== undefined) { + this.timeout = setTimeout(function () { + that.element.fadeOut(100, function () {that.element.html('');}); + that.timeout = null; + }, timeout) + }; + }; + + + NotificationWidget.prototype.get_message = function () { + return this.element.html(); + }; + + + IPython.NotificationWidget = NotificationWidget; + + return IPython; + +}(IPython)); + diff --git a/IPython/frontend/html/notebook/static/js/printnotebookmain.js b/IPython/frontend/html/notebook/static/js/printnotebookmain.js index ce5ec98..55f168c 100644 --- a/IPython/frontend/html/notebook/static/js/printnotebookmain.js +++ b/IPython/frontend/html/notebook/static/js/printnotebookmain.js @@ -79,16 +79,15 @@ $(document).ready(function () { $('div#main_app').addClass('border-box-sizing ui-widget ui-widget-content'); $('div#notebook_panel').addClass('border-box-sizing ui-widget'); - IPython.save_widget = new IPython.SaveWidget('span#save_widget'); IPython.login_widget = new IPython.LoginWidget('span#login_widget'); IPython.notebook = new IPython.Notebook('div#notebook'); + IPython.save_widget = new IPython.SaveWidget('span#save_widget'); // These have display: none in the css file and are made visible here to prevent FLOUC. $('div#header').css('display','block'); $('div#main_app').css('display','block'); - // Perform these actions after the notebook has been loaded. - IPython.notebook.load_notebook(function () {}); + IPython.notebook.load_notebook($('body').data('notebookId')); }); diff --git a/IPython/frontend/html/notebook/static/js/savewidget.js b/IPython/frontend/html/notebook/static/js/savewidget.js index ad1f5f3..2ffaf31 100644 --- a/IPython/frontend/html/notebook/static/js/savewidget.js +++ b/IPython/frontend/html/notebook/static/js/savewidget.js @@ -15,8 +15,6 @@ var IPython = (function (IPython) { var SaveWidget = function (selector) { this.selector = selector; - this.notebook_name_blacklist_re = /[\/\\]/; - this.last_saved_name = ''; if (this.selector !== undefined) { this.element = $(selector); this.style(); @@ -43,11 +41,19 @@ var IPython = (function (IPython) { }, function () { $(this).removeClass("ui-state-hover"); }); - }; - - - SaveWidget.prototype.save_notebook = function () { - IPython.notebook.save_notebook(); + $([IPython.events]).on('notebook_loaded.Notebook', function () { + that.set_last_saved(); + that.update_notebook_name(); + that.update_document_title(); + }); + $([IPython.events]).on('notebook_saved.Notebook', function () { + that.set_last_saved(); + that.update_notebook_name(); + that.update_document_title(); + }); + $([IPython.events]).on('notebook_save_failed.Notebook', function () { + that.set_save_status(''); + }); }; @@ -61,7 +67,7 @@ var IPython = (function (IPython) { dialog.append( $('<input/>').attr('type','text').attr('size','25') .addClass('ui-widget ui-widget-content') - .attr('value',that.get_notebook_name()) + .attr('value',IPython.notebook.get_notebook_name()) ); // $(document).append(dialog); dialog.dialog({ @@ -73,15 +79,15 @@ var IPython = (function (IPython) { buttons : { "OK": function () { var new_name = $(this).find('input').attr('value'); - if (!that.test_notebook_name(new_name)) { + if (!IPython.notebook.test_notebook_name(new_name)) { $(this).find('h3').html( "Invalid notebook name. Notebook names must "+ "have 1 or more characters and can contain any characters " + "except / and \\. Please enter a new notebook name:" ); } else { - that.set_notebook_name(new_name); - that.save_notebook(); + IPython.notebook.set_notebook_name(new_name); + IPython.notebook.save_notebook(); $(this).dialog('close'); } }, @@ -92,82 +98,36 @@ var IPython = (function (IPython) { }); } - SaveWidget.prototype.notebook_saved = function () { - this.set_document_title(); - this.last_saved_name = this.get_notebook_name(); - }; - - SaveWidget.prototype.get_notebook_name = function () { - return this.element.find('span#notebook_name').html(); - }; - - - SaveWidget.prototype.set_notebook_name = function (nbname) { + SaveWidget.prototype.update_notebook_name = function () { + var nbname = IPython.notebook.get_notebook_name(); this.element.find('span#notebook_name').html(nbname); - this.set_document_title(); - this.last_saved_name = nbname; }; - SaveWidget.prototype.set_document_title = function () { - nbname = this.get_notebook_name(); + SaveWidget.prototype.update_document_title = function () { + var nbname = IPython.notebook.get_notebook_name(); document.title = nbname; }; - - - SaveWidget.prototype.get_notebook_id = function () { - return $('body').data('notebookId'); - }; SaveWidget.prototype.update_url = function () { - var notebook_id = this.get_notebook_id(); - if (notebook_id !== '') { + var notebook_id = IPython.notebook.get_notebook_id(); + if (notebook_id !== null) { var new_url = $('body').data('baseProjectUrl') + notebook_id; window.history.replaceState({}, '', new_url); }; }; - SaveWidget.prototype.test_notebook_name = function (nbname) { - nbname = nbname || ''; - if (this.notebook_name_blacklist_re.test(nbname) == false && nbname.length>0) { - return true; - } else { - return false; - }; - }; + SaveWidget.prototype.set_save_status = function (msg) { + this.element.find('span#save_status').html(msg); + } SaveWidget.prototype.set_last_saved = function () { var d = new Date(); - $('#save_status').html('Last saved: '+d.format('mmm dd h:MM TT')); - - }; - - SaveWidget.prototype.reset_status = function () { - this.element.find('span#save_status').html(''); - }; - - - SaveWidget.prototype.status_last_saved = function () { - this.set_last_saved(); - }; - - - SaveWidget.prototype.status_saving = function () { - this.element.find('span#save_status').html('Saving...'); - }; - - - SaveWidget.prototype.status_save_failed = function () { - this.element.find('span#save_status').html('Save failed'); - }; - - - SaveWidget.prototype.status_loading = function () { - this.element.find('span#save_status').html('Loading...'); + this.set_save_status('Last saved: '+d.format('mmm dd h:MM TT')); }; diff --git a/IPython/frontend/html/notebook/static/js/toolbar.js b/IPython/frontend/html/notebook/static/js/toolbar.js index df0de25..2ecdfa0 100644 --- a/IPython/frontend/html/notebook/static/js/toolbar.js +++ b/IPython/frontend/html/notebook/static/js/toolbar.js @@ -72,8 +72,9 @@ var IPython = (function (IPython) { ToolBar.prototype.bind_events = function () { + var that = this; this.element.find('#save_b').click(function () { - IPython.save_widget.save_notebook(); + IPython.notebook.save_notebook(); }); this.element.find('#cut_b').click(function () { IPython.notebook.cut_cell(); @@ -124,12 +125,13 @@ var IPython = (function (IPython) { IPython.notebook.to_heading(undefined, 6); }; }); - - }; - - - ToolBar.prototype.set_cell_type = function (cell_type) { - this.element.find('#cell_type').val(cell_type); + $([IPython.events]).on('selected_cell_type_changed', function (event, data) { + if (data.cell_type === 'heading') { + that.element.find('#cell_type').val(data.cell_type+data.level); + } else { + that.element.find('#cell_type').val(data.cell_type); + } + }); }; diff --git a/IPython/frontend/html/notebook/templates/notebook.html b/IPython/frontend/html/notebook/templates/notebook.html index 242a5d0..7b0b087 100644 --- a/IPython/frontend/html/notebook/templates/notebook.html +++ b/IPython/frontend/html/notebook/templates/notebook.html @@ -54,10 +54,9 @@ <button id="login">Login</button> {% end %} </span> - - <span id="kernel_status">Idle</span> </div> +<div id="menubar_container"> <div id="menubar"> <ul id="menus"> <li><a href="#">File</a> @@ -153,6 +152,9 @@ </ul> </div> +<div id="notification"></div> +</div> + <div id="toolbar"> @@ -220,12 +222,12 @@ <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script> <script src="{{ static_url("js/namespace.js") }}" type="text/javascript" charset="utf-8"></script> +<script src="{{ static_url("js/events.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/utils.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/cell.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/codecell.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/textcell.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/kernel.js") }}" type="text/javascript" charset="utf-8"></script> -<script src="{{ static_url("js/kernelstatus.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/layout.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/savewidget.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/quickhelp.js") }}" type="text/javascript" charset="utf-8"></script> @@ -234,6 +236,7 @@ <script src="{{ static_url("js/menubar.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/toolbar.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/notebook.js") }}" type="text/javascript" charset="utf-8"></script> +<script src="{{ static_url("js/notificationwidget.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/notebookmain.js") }}" type="text/javascript" charset="utf-8"></script> </body> diff --git a/IPython/frontend/html/notebook/templates/printnotebook.html b/IPython/frontend/html/notebook/templates/printnotebook.html index 003fe33..2849e61 100644 --- a/IPython/frontend/html/notebook/templates/printnotebook.html +++ b/IPython/frontend/html/notebook/templates/printnotebook.html @@ -17,10 +17,7 @@ <link rel="stylesheet" href="{{ static_url("jquery/css/themes/base/jquery-ui.min.css") }}" type="text/css" /> <link rel="stylesheet" href="{{ static_url("codemirror/lib/codemirror.css") }}"> - <link rel="stylesheet" href="{{ static_url("codemirror/mode/markdown/markdown.css") }}"> - <link rel="stylesheet" href="{{ static_url("codemirror/mode/rst/rst.css") }}"> <link rel="stylesheet" href="{{ static_url("codemirror/theme/ipython.css") }}"> - <link rel="stylesheet" href="{{ static_url("codemirror/theme/default.css") }}"> <link rel="stylesheet" href="{{ static_url("prettify/prettify.css") }}"/> @@ -88,6 +85,7 @@ <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script> <script src="{{ static_url("js/namespace.js") }}" type="text/javascript" charset="utf-8"></script> +<script src="{{ static_url("js/events.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/utils.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/cell.js") }}" type="text/javascript" charset="utf-8"></script> <script src="{{ static_url("js/codecell.js") }}" type="text/javascript" charset="utf-8"></script>