diff --git a/IPython/frontend/html/notebook/static/js/cell.js b/IPython/frontend/html/notebook/static/js/cell.js index 68c876976..9536c9b97 100644 --- a/IPython/frontend/html/notebook/static/js/cell.js +++ b/IPython/frontend/html/notebook/static/js/cell.js @@ -19,6 +19,7 @@ var IPython = (function (IPython) { this.read_only = false; this.selected = false; this.element = null; + this.metadata = {}; this.create_element(); if (this.element !== null) { this.element.data("cell", this); @@ -90,10 +91,16 @@ var IPython = (function (IPython) { Cell.prototype.toJSON = function () { + var data = {}; + data.metadata = this.metadata; + return data; }; Cell.prototype.fromJSON = function (data) { + if (data.metadata !== undefined) { + this.metadata = data.metadata; + } }; diff --git a/IPython/frontend/html/notebook/static/js/codecell.js b/IPython/frontend/html/notebook/static/js/codecell.js index 41e7156ed..5c5ead2e2 100644 --- a/IPython/frontend/html/notebook/static/js/codecell.js +++ b/IPython/frontend/html/notebook/static/js/codecell.js @@ -22,6 +22,7 @@ var IPython = (function (IPython) { this.code_mirror = null; this.input_prompt_number = null; this.tooltip_on_tab = true; + this.collapsed = false; IPython.Cell.apply(this, arguments); }; @@ -200,17 +201,20 @@ var IPython = (function (IPython) { CodeCell.prototype.collapse = function () { - this.output_area.collapse(); + this.collapsed = true; + this.output_area.collapse(); }; CodeCell.prototype.expand = function () { - this.output_area.expand(); + this.collapsed = false; + this.output_area.expand(); }; CodeCell.prototype.toggle_output = function () { - this.output_area.toggle_output(); + this.collapsed = Boolean(1 - this.collapsed); + this.output_area.toggle_output(); }; @@ -264,6 +268,7 @@ var IPython = (function (IPython) { // JSON serialization CodeCell.prototype.fromJSON = function (data) { + IPython.Cell.prototype.fromJSON.apply(this, arguments); if (data.cell_type === 'code') { if (data.input !== undefined) { this.set_text(data.input); @@ -289,7 +294,7 @@ var IPython = (function (IPython) { CodeCell.prototype.toJSON = function () { - var data = {}; + var data = IPython.Cell.prototype.toJSON.apply(this); data.input = this.get_text(); data.cell_type = 'code'; if (this.input_prompt_number) { diff --git a/IPython/frontend/html/notebook/static/js/notebook.js b/IPython/frontend/html/notebook/static/js/notebook.js index 12268e9a7..7c02bf7ad 100644 --- a/IPython/frontend/html/notebook/static/js/notebook.js +++ b/IPython/frontend/html/notebook/static/js/notebook.js @@ -25,11 +25,14 @@ var IPython = (function (IPython) { this.paste_enabled = false; this.dirty = false; this.metadata = {}; + // single worksheet for now + this.worksheet_metadata = {}; this.control_key_active = false; this.notebook_id = null; this.notebook_name = null; this.notebook_name_blacklist_re = /[\/\\:]/; this.nbformat = 3 // Increment this when changing the nbformat + this.nbformat_minor = 0 // Increment this when changing the nbformat this.style(); this.create_elements(); this.bind_events(); @@ -1018,6 +1021,9 @@ var IPython = (function (IPython) { // Only handle 1 worksheet for now. var worksheet = data.worksheets[0]; if (worksheet !== undefined) { + if (worksheet.metadata) { + this.worksheet_metadata = worksheet.metadata; + } var new_cells = worksheet.cells; ncells = new_cells.length; var cell_data = null; @@ -1034,6 +1040,27 @@ var IPython = (function (IPython) { new_cell.fromJSON(cell_data); }; }; + if (data.worksheets.length > 1) { + var dialog = $('
'); + dialog.html("This notebook has " + data.worksheets.length + " worksheets, " + + "but this version of IPython can only handle the first. " + + "If you save this notebook, worksheets after the first will be lost." + ); + this.element.append(dialog); + dialog.dialog({ + resizable: false, + modal: true, + title: "Multiple worksheets", + closeText: "", + close: function(event, ui) {$(this).dialog('destroy').remove();}, + buttons : { + "OK": function () { + $(this).dialog('close'); + } + }, + width: 400 + }); + } }; @@ -1046,7 +1073,10 @@ var IPython = (function (IPython) { }; var data = { // Only handle 1 worksheet for now. - worksheets : [{cells:cell_array}], + worksheets : [{ + cells: cell_array, + metadata: this.worksheet_metadata + }], metadata : this.metadata }; return data; @@ -1057,6 +1087,7 @@ var IPython = (function (IPython) { var data = this.toJSON(); data.metadata.name = this.notebook_name; data.nbformat = this.nbformat; + data.nbformat_minor = this.nbformat_minor; // We do the call with settings so we can set cache to false. var settings = { processData : false, @@ -1133,6 +1164,31 @@ var IPython = (function (IPython) { }, width: 400 }); + } else if (data.orig_nbformat_minor !== undefined && data.nbformat_minor !== data.orig_nbformat_minor) { + var that = this; + var orig_vs = 'v' + data.nbformat + '.' + data.orig_nbformat_minor; + var this_vs = 'v' + data.nbformat + '.' + this.nbformat_minor; + msg = "This notebook is version " + orig_vs + ", but we only fully support up to " + + this_vs + ". You can still work with this notebook, but some features " + + "introduced in later notebook versions may not be available." + + var dialog = $('
'); + dialog.html(msg); + this.element.append(dialog); + dialog.dialog({ + resizable: false, + modal: true, + title: "Newer Notebook", + closeText: "", + close: function(event, ui) {$(this).dialog('destroy').remove();}, + buttons : { + "OK": function () { + $(this).dialog('close'); + } + }, + width: 400 + }); + } // Create the kernel after the notebook is completely loaded to prevent // code execution upon loading, which is a security risk. diff --git a/IPython/frontend/html/notebook/static/js/textcell.js b/IPython/frontend/html/notebook/static/js/textcell.js index 2e52a7538..3d07d3a44 100644 --- a/IPython/frontend/html/notebook/static/js/textcell.js +++ b/IPython/frontend/html/notebook/static/js/textcell.js @@ -155,6 +155,7 @@ var IPython = (function (IPython) { TextCell.prototype.fromJSON = function (data) { + IPython.Cell.prototype.fromJSON.apply(this, arguments); if (data.cell_type === this.cell_type) { if (data.source !== undefined) { this.set_text(data.source); @@ -170,7 +171,7 @@ var IPython = (function (IPython) { TextCell.prototype.toJSON = function () { - var data = {}; + var data = IPython.Cell.prototype.toJSON.apply(this); data.cell_type = this.cell_type; data.source = this.get_text(); return data;