diff --git a/IPython/html/static/notebook/js/cell.js b/IPython/html/static/notebook/js/cell.js
index 7d8506a..568eb1e 100644
--- a/IPython/html/static/notebook/js/cell.js
+++ b/IPython/html/static/notebook/js/cell.js
@@ -123,7 +123,12 @@ var IPython = (function (IPython) {
this.code_mirror.on("change", function(cm, change) {
$([IPython.events]).trigger("set_dirty.Notebook", {value: true});
});
- }
+ };
+ if (this.code_mirror) {
+ this.code_mirror.on('focus', function(cm, change) {
+ $([IPython.events]).trigger('edit_mode.Cell', {cell: that});
+ });
+ };
};
/**
@@ -143,12 +148,14 @@ var IPython = (function (IPython) {
* @return is the action being taken
*/
Cell.prototype.select = function () {
+ console.log('Cell.select');
if (!this.selected) {
this.element.addClass('selected');
this.element.removeClass('unselected');
this.selected = true;
return true;
} else {
+ console.log('WARNING: select');
return false;
};
};
@@ -159,12 +166,14 @@ var IPython = (function (IPython) {
* @return is the action being taken
*/
Cell.prototype.unselect = function () {
+ console.log('Cell.unselect');
if (this.selected) {
this.element.addClass('unselected');
this.element.removeClass('selected');
this.selected = false;
return true;
} else {
+ console.log('WARNING: unselect');
return false;
};
};
@@ -175,12 +184,14 @@ var IPython = (function (IPython) {
* @return is the action being taken
*/
Cell.prototype.render = function () {
+ console.log('Cell.render');
if (!this.rendered) {
this.element.addClass('rendered');
this.element.removeClass('unrendered');
this.rendered = true;
return true;
} else {
+ console.log('WARNING: render');
return false;
};
};
@@ -191,12 +202,14 @@ var IPython = (function (IPython) {
* @return is the action being taken
*/
Cell.prototype.unrender = function () {
+ console.log('Cell.unrender');
if (this.rendered) {
this.element.addClass('unrendered');
this.element.removeClass('rendered');
this.rendered = false;
return true;
} else {
+ console.log('WARNING: unrender');
return false;
};
};
@@ -207,12 +220,14 @@ var IPython = (function (IPython) {
* @return is the action being taken
*/
Cell.prototype.command_mode = function () {
+ console.log('Cell.command_mode:', this.mode);
if (this.mode !== 'command') {
this.element.addClass('command_mode');
this.element.removeClass('edit_mode');
this.mode = 'command';
return true;
} else {
+ console.log('WARNING: command_mode');
return false;
};
};
@@ -223,12 +238,14 @@ var IPython = (function (IPython) {
* @return is the action being taken
*/
Cell.prototype.edit_mode = function () {
+ console.log('Cell.edit_mode:', this.mode);
if (this.mode !== 'edit') {
this.element.addClass('edit_mode');
this.element.removeClass('command_mode');
this.mode = 'edit';
return true;
} else {
+ console.log('WARNING: edit_mode');
return false;
};
}
@@ -246,26 +263,11 @@ var IPython = (function (IPython) {
* @method focus_editor
*/
Cell.prototype.focus_editor = function () {
- this.code_mirror.refresh();
+ this.refresh();
this.code_mirror.focus();
}
/**
- * should be overritten by subclass
- * @method get_text
- */
- Cell.prototype.get_text = function () {
- };
-
- /**
- * should be overritten by subclass
- * @method set_text
- * @param {string} text
- */
- Cell.prototype.set_text = function (text) {
- };
-
- /**
* Refresh codemirror instance
* @method refresh
*/
@@ -273,20 +275,19 @@ var IPython = (function (IPython) {
this.code_mirror.refresh();
};
-
/**
* should be overritten by subclass
- * @method edit
- **/
- Cell.prototype.edit = function () {
+ * @method get_text
+ */
+ Cell.prototype.get_text = function () {
};
-
/**
* should be overritten by subclass
- * @method render
- **/
- Cell.prototype.render = function () {
+ * @method set_text
+ * @param {string} text
+ */
+ Cell.prototype.set_text = function (text) {
};
/**
diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js
index 9069279..9f20e2f 100644
--- a/IPython/html/static/notebook/js/codecell.js
+++ b/IPython/html/static/notebook/js/codecell.js
@@ -139,6 +139,16 @@ var IPython = (function (IPython) {
this.completer = new IPython.Completer(this);
};
+ /** @method bind_events */
+ CodeCell.prototype.bind_events = function () {
+ IPython.Cell.prototype.bind_events.apply(this);
+ var that = this;
+
+ this.element.focusout(
+ function() { that.auto_highlight(); }
+ );
+ };
+
/**
* This method gets called in CodeMirror's onKeyDown/onKeyPress
* handlers and is used to provide custom key handling. Its return
@@ -308,44 +318,43 @@ var IPython = (function (IPython) {
// Basic cell manipulation.
CodeCell.prototype.select = function () {
- var continue = IPython.Cell.prototype.select.apply(this);
- if (continue) {
+ var cont = IPython.Cell.prototype.select.apply(this);
+ console.log('CodeCell.select', cont);
+ if (cont) {
this.code_mirror.refresh();
this.auto_highlight();
};
- return continue;
+ return cont;
};
CodeCell.prototype.render = function () {
- var continue = IPython.Cell.prototype.render.apply(this);
- if (continue) {
- this.execute();
- };
- return continue;
+ var cont = IPython.Cell.prototype.render.apply(this);
+ console.log('CodeCell.render');
+ // Always execute, even if we are already in the rendered state
+ return cont;
};
-
+
CodeCell.prototype.unrender = function () {
- var continue = IPython.Cell.prototype.unrender.apply(this);
- if (continue) {
- this.clear_output(true, true, true);
- };
- return continue;
+ // CodeCell is always rendered
+ return false;
};
CodeCell.prototype.command_mode = function () {
- var continue = IPython.Cell.prototype.command_mode.apply(this);
- if (continue) {
+ var cont = IPython.Cell.prototype.command_mode.apply(this);
+ console.log('CodeCell.command_mode');
+ if (cont) {
this.focus_cell();
};
- return continue;
+ return cont;
}
CodeCell.prototype.edit_mode = function () {
- var continue = IPython.Cell.prototype.edit_mode.apply(this);
- if (continue) {
+ var cont = IPython.Cell.prototype.edit_mode.apply(this);
+ console.log('CodeCell.edit_mode');
+ if (cont) {
this.focus_editor();
};
- return continue;
+ return cont;
}
CodeCell.prototype.select_all = function () {
diff --git a/IPython/html/static/notebook/js/notebook.js b/IPython/html/static/notebook/js/notebook.js
index 3eebb2f..d97a426 100644
--- a/IPython/html/static/notebook/js/notebook.js
+++ b/IPython/html/static/notebook/js/notebook.js
@@ -39,6 +39,8 @@ var IPython = (function (IPython) {
this.undelete_index = null;
this.undelete_below = false;
this.paste_enabled = false;
+ this.mode = 'command';
+ this.edit_index = null;
this.set_dirty(false);
this.metadata = {};
this._checkpoint_after_save = false;
@@ -74,7 +76,7 @@ var IPython = (function (IPython) {
* @method baseProjectUrl
* @return {String} The base project URL
*/
- Notebook.prototype.baseProjectUrl = function(){
+ Notebook.prototype.baseProjectUrl = function() {
return this._baseProjectUrl || $('body').data('baseProjectUrl');
};
@@ -131,6 +133,12 @@ var IPython = (function (IPython) {
var index = that.find_cell_index(data.cell);
that.select(index);
});
+
+ $([IPython.events]).on('edit_mode.Cell', function (event, data) {
+ var index = that.find_cell_index(data.cell);
+ that.select(index);
+ that.edit_mode();
+ });
$([IPython.events]).on('status_autorestarting.Kernel', function () {
IPython.dialog.modal({
@@ -144,220 +152,222 @@ var IPython = (function (IPython) {
});
});
-
$(document).keydown(function (event) {
- // Save (CTRL+S) or (AppleKey+S)
- //metaKey = applekey on mac
+ // Event handlers for both command and edit mode
if ((event.ctrlKey || event.metaKey) && event.keyCode==83) {
+ // Save (CTRL+S) or (Command+S on Mac)
that.save_checkpoint();
event.preventDefault();
return false;
} else if (event.which === key.ESC) {
// Intercept escape at highest level to avoid closing
// websocket connection with firefox
- IPython.pager.collapse();
event.preventDefault();
+ // Don't return yet to allow edit/command modes to handle
} else if (event.which === key.SHIFT) {
// ignore shift keydown
return true;
- }
- if (event.which === key.UPARROW && !event.shiftKey) {
- var cell = that.get_selected_cell();
- if (cell && cell.at_top()) {
- event.preventDefault();
- that.select_prev();
- };
- } else if (event.which === key.DOWNARROW && !event.shiftKey) {
- var cell = that.get_selected_cell();
- if (cell && cell.at_bottom()) {
- event.preventDefault();
- that.select_next();
- };
} else if (event.which === key.ENTER && event.shiftKey) {
- that.execute_selected_cell();
+ that.execute_selected_cell('shift');
return false;
} else if (event.which === key.ENTER && event.altKey) {
// Execute code cell, and insert new in place
- that.execute_selected_cell();
- // Only insert a new cell, if we ended up in an already populated cell
- if (/\S/.test(that.get_selected_cell().get_text()) == true) {
- that.insert_cell_above('code');
- }
+ that.execute_selected_cell('alt');
return false;
} else if (event.which === key.ENTER && event.ctrlKey) {
- that.execute_selected_cell({terminal:true});
- return false;
- } else if (event.which === 77 && event.ctrlKey && that.control_key_active == false) {
- that.control_key_active = true;
- return false;
- } else if (event.which === 88 && that.control_key_active) {
- // Cut selected cell = x
- that.cut_cell();
- that.control_key_active = false;
- return false;
- } else if (event.which === 67 && that.control_key_active) {
- // Copy selected cell = c
- that.copy_cell();
- that.control_key_active = false;
- return false;
- } else if (event.which === 86 && that.control_key_active) {
- // Paste below selected cell = v
- that.paste_cell_below();
- that.control_key_active = false;
- return false;
- } else if (event.which === 68 && that.control_key_active) {
- // Delete selected cell = d
- that.delete_cell();
- that.control_key_active = false;
- return false;
- } else if (event.which === 65 && that.control_key_active) {
- // Insert code cell above selected = a
- that.insert_cell_above('code');
- that.control_key_active = false;
- return false;
- } else if (event.which === 66 && that.control_key_active) {
- // Insert code cell below selected = b
- that.insert_cell_below('code');
- that.control_key_active = false;
- return false;
- } else if (event.which === 89 && that.control_key_active) {
- // To code = y
- that.to_code();
- that.control_key_active = false;
- return false;
- } else if (event.which === 77 && that.control_key_active) {
- // To markdown = m
- that.to_markdown();
- that.control_key_active = false;
- return false;
- } else if (event.which === 84 && that.control_key_active) {
- // To Raw = t
- that.to_raw();
- that.control_key_active = false;
+ that.execute_selected_cell('ctrl');
return false;
- } else if (event.which === 49 && that.control_key_active) {
- // To Heading 1 = 1
- that.to_heading(undefined, 1);
- that.control_key_active = false;
- return false;
- } else if (event.which === 50 && that.control_key_active) {
- // To Heading 2 = 2
- that.to_heading(undefined, 2);
- that.control_key_active = false;
- return false;
- } else if (event.which === 51 && that.control_key_active) {
- // To Heading 3 = 3
- that.to_heading(undefined, 3);
- that.control_key_active = false;
- return false;
- } else if (event.which === 52 && that.control_key_active) {
- // To Heading 4 = 4
- that.to_heading(undefined, 4);
- that.control_key_active = false;
- return false;
- } else if (event.which === 53 && that.control_key_active) {
- // To Heading 5 = 5
- that.to_heading(undefined, 5);
- that.control_key_active = false;
- return false;
- } else if (event.which === 54 && that.control_key_active) {
- // To Heading 6 = 6
- that.to_heading(undefined, 6);
- that.control_key_active = false;
- return false;
- } else if (event.which === 79 && that.control_key_active) {
- // Toggle output = o
- if (event.shiftKey){
- that.toggle_output_scroll();
- } else {
- that.toggle_output();
- }
- that.control_key_active = false;
- return false;
- } else if (event.which === 83 && that.control_key_active) {
- // Save notebook = s
- that.save_checkpoint();
- that.control_key_active = false;
- return false;
- } else if (event.which === 74 && that.control_key_active) {
- // Move cell down = j
- that.move_cell_down();
- that.control_key_active = false;
- return false;
- } else if (event.which === 75 && that.control_key_active) {
- // Move cell up = k
- that.move_cell_up();
- that.control_key_active = false;
- return false;
- } else if (event.which === 80 && that.control_key_active) {
- // Select previous = p
- that.select_prev();
- that.control_key_active = false;
- return false;
- } else if (event.which === 78 && that.control_key_active) {
- // Select next = n
- that.select_next();
- that.control_key_active = false;
- return false;
- } else if (event.which === 76 && that.control_key_active) {
- // Toggle line numbers = l
- that.cell_toggle_line_numbers();
- that.control_key_active = false;
- return false;
- } else if (event.which === 73 && that.control_key_active) {
- // Interrupt kernel = i
- that.session.interrupt_kernel();
- that.control_key_active = false;
- return false;
- } else if (event.which === 190 && that.control_key_active) {
- // Restart kernel = . # matches qt console
- that.restart_kernel();
- that.control_key_active = false;
- return false;
- } else if (event.which === 72 && that.control_key_active) {
- // Show keyboard shortcuts = h
- IPython.quick_help.show_keyboard_shortcuts();
- that.control_key_active = false;
- return false;
- } else if (event.which === 90 && that.control_key_active) {
- // Undo last cell delete = z
- that.undelete();
- that.control_key_active = false;
- return false;
- } else if ((event.which === 189 || event.which === 173) &&
- that.control_key_active) {
- // how fun! '-' is 189 in Chrome, but 173 in FF and Opera
- // Split cell = -
- that.split_cell();
- that.control_key_active = false;
- return false;
- } else if (that.control_key_active) {
- that.control_key_active = false;
- return true;
}
+
+ // Event handlers for edit mode
+ if (that.mode === 'edit') {
+ if (event.which === key.ESC) {
+ // ESC
+ that.command_mode();
+ return false;
+ } else if (event.which === 77 && event.ctrlKey) {
+ // Ctrl-m
+ that.command_mode();
+ return false;
+ } else if (event.which === key.UPARROW && !event.shiftKey) {
+ var cell = that.get_selected_cell();
+ if (cell && cell.at_top()) {
+ event.preventDefault();
+ that.command_mode()
+ that.select_prev();
+ that.edit_mode();
+ return false;
+ };
+ } else if (event.which === key.DOWNARROW && !event.shiftKey) {
+ var cell = that.get_selected_cell();
+ if (cell && cell.at_bottom()) {
+ event.preventDefault();
+ that.command_mode()
+ that.select_next();
+ that.edit_mode();
+ return false;
+ };
+ };
+ // Event handlers for command mode
+ } else if (that.mode === 'command' && !(event.ctrlKey || event.altKey)) {
+ if (event.which === key.ENTER && !(event.ctrlKey || event.altKey || event.shiftKey)) {
+ // Enter edit mode = ENTER alone
+ that.edit_mode();
+ return false
+ } else if (event.which === key.UPARROW && !event.shiftKey) {
+ var index = that.get_selected_index();
+ if (index !== 0 && index !== null) {
+ that.select_prev();
+ var cell = that.get_selected_cell();
+ cell.focus_cell();
+ };
+ return false;
+ } else if (event.which === key.DOWNARROW && !event.shiftKey) {
+ var index = that.get_selected_index();
+ if (index !== (that.ncells()-1) && index !== null) {
+ that.select_next();
+ var cell = that.get_selected_cell();
+ cell.focus_cell();
+ };
+ return false;
+ } else if (event.which === 88) {
+ // Cut selected cell = x
+ that.cut_cell();
+ return false;
+ } else if (event.which === 67) {
+ // Copy selected cell = c
+ that.copy_cell();
+ return false;
+ } else if (event.which === 86) {
+ // Paste below selected cell = v
+ that.paste_cell_below();
+ return false;
+ } else if (event.which === 68) {
+ // Delete selected cell = d
+ that.delete_cell();
+ return false;
+ } else if (event.which === 65) {
+ // Insert code cell above selected = a
+ that.insert_cell_above('code');
+ that.select_prev();
+ return false;
+ } else if (event.which === 66) {
+ // Insert code cell below selected = b
+ that.insert_cell_below('code');
+ that.select_next();
+ return false;
+ } else if (event.which === 89) {
+ // To code = y
+ that.to_code();
+ return false;
+ } else if (event.which === 77) {
+ // To markdown = m
+ that.to_markdown();
+ return false;
+ } else if (event.which === 84) {
+ // To Raw = t
+ that.to_raw();
+ return false;
+ } else if (event.which === 49) {
+ // To Heading 1 = 1
+ that.to_heading(undefined, 1);
+ return false;
+ } else if (event.which === 50) {
+ // To Heading 2 = 2
+ that.to_heading(undefined, 2);
+ return false;
+ } else if (event.which === 51) {
+ // To Heading 3 = 3
+ that.to_heading(undefined, 3);
+ return false;
+ } else if (event.which === 52) {
+ // To Heading 4 = 4
+ that.to_heading(undefined, 4);
+ return false;
+ } else if (event.which === 53) {
+ // To Heading 5 = 5
+ that.to_heading(undefined, 5);
+ return false;
+ } else if (event.which === 54) {
+ // To Heading 6 = 6
+ that.to_heading(undefined, 6);
+ return false;
+ } else if (event.which === 79) {
+ // Toggle output = o
+ if (event.shiftKey) {
+ that.toggle_output_scroll();
+ } else {
+ that.toggle_output();
+ };
+ return false;
+ } else if (event.which === 83) {
+ // Save notebook = s
+ that.save_checkpoint();
+ that.control_key_active = false;
+ return false;
+ } else if (event.which === 74) {
+ // Move cell down = j
+ that.move_cell_down();
+ return false;
+ } else if (event.which === 75) {
+ // Move cell up = k
+ that.move_cell_up();
+ return false;
+ } else if (event.which === 80) {
+ // Select previous = p
+ that.select_prev();
+ return false;
+ } else if (event.which === 78) {
+ // Select next = n
+ that.select_next();
+ return false;
+ } else if (event.which === 76) {
+ // Toggle line numbers = l
+ that.cell_toggle_line_numbers();
+ return false;
+ } else if (event.which === 73) {
+ // Interrupt kernel = i
+ that.kernel.interrupt();
+ return false;
+ } else if (event.which === 190) {
+ // Restart kernel = . # matches qt console
+ that.restart_kernel();
+ return false;
+ } else if (event.which === 72) {
+ // Show keyboard shortcuts = h
+ IPython.quick_help.show_keyboard_shortcuts();
+ return false;
+ } else if (event.which === 90) {
+ // Undo last cell delete = z
+ that.undelete();
+ return false;
+ };
+ };
+
+ // If we havn't handled it, let someone else.
return true;
});
- var collapse_time = function(time){
+ var collapse_time = function (time) {
var app_height = $('#ipython-main-app').height(); // content height
var splitter_height = $('div#pager_splitter').outerHeight(true);
var new_height = app_height - splitter_height;
that.element.animate({height : new_height + 'px'}, time);
- }
+ };
- this.element.bind('collapse_pager', function (event,extrap) {
+ this.element.bind('collapse_pager', function (event, extrap) {
var time = (extrap != undefined) ? ((extrap.duration != undefined ) ? extrap.duration : 'fast') : 'fast';
collapse_time(time);
});
- var expand_time = function(time) {
+ var expand_time = function (time) {
var app_height = $('#ipython-main-app').height(); // content height
var splitter_height = $('div#pager_splitter').outerHeight(true);
var pager_height = $('div#pager').outerHeight(true);
var new_height = app_height - pager_height - splitter_height;
that.element.animate({height : new_height + 'px'}, time);
- }
+ };
this.element.bind('expand_pager', function (event, extrap) {
var time = (extrap != undefined) ? ((extrap.duration != undefined ) ? extrap.duration : 'fast') : 'fast';
@@ -653,6 +663,7 @@ var IPython = (function (IPython) {
this.get_cell(sindex).unselect();
};
var cell = this.get_cell(index);
+ console.log('Notebook.select', index);
cell.select();
if (cell.cell_type === 'heading') {
$([IPython.events]).trigger('selected_cell_type_changed.Notebook',
@@ -692,6 +703,48 @@ var IPython = (function (IPython) {
};
+ // Edit/Command mode
+
+ /**
+ * Enter command mode for the currently selected cell
+ *
+ * @method command_mode
+ */
+ Notebook.prototype.command_mode = function () {
+ console.log('Notebook.command_mode', this.mode, this.edit_index);
+ if (this.mode !== 'command') {
+ var cell = this.get_cell(this.edit_index);
+ if (cell) {
+ cell.command_mode();
+ this.mode = 'command';
+ this.edit_index = null;
+ };
+ };
+ };
+
+ /**
+ * Enter edit mode for the currently selected cell
+ *
+ * @method editmode
+ */
+ Notebook.prototype.edit_mode = function () {
+ var index = this.get_selected_index();
+ console.log('Notebook.edit_mode', this.mode, index);
+ if (index !== this.edit_index) {
+ if (this.edit_index !== null) {
+ var old_cell = this.get_cell(this.edit_index)
+ old_cell.command_mode();
+ }
+ var cell = this.get_cell(index);
+ if (cell) {
+ cell.edit_mode();
+ this.mode = 'edit';
+ this.edit_index = index;
+ };
+ };
+ };
+
+
// Cell movement
/**
@@ -804,10 +857,12 @@ var IPython = (function (IPython) {
cell = new IPython.HeadingCell();
}
- if(this._insert_element_at_index(cell.element,index)){
+ if(this._insert_element_at_index(cell.element,index)) {
cell.render();
- this.select(this.find_cell_index(cell));
$([IPython.events]).trigger('create.Cell', {'cell': cell, 'index': index});
+ cell.refresh();
+ // TODO: should we really get rid of this?
+ //this.select(this.find_cell_index(cell));
this.set_dirty(true);
}
}
@@ -952,6 +1007,8 @@ var IPython = (function (IPython) {
// to this state, instead of a blank cell
target_cell.code_mirror.clearHistory();
source_element.remove();
+ this.select(i);
+ this.edit_mode();
this.set_dirty(true);
};
};
@@ -1440,31 +1497,41 @@ var IPython = (function (IPython) {
* @method execute_selected_cell
* @param {Object} options Customize post-execution behavior
*/
- Notebook.prototype.execute_selected_cell = function (options) {
- // add_new: should a new cell be added if we are at the end of the nb
- // terminal: execute in terminal mode, which stays in the current cell
- var default_options = {terminal: false, add_new: true};
- $.extend(default_options, options);
+ Notebook.prototype.execute_selected_cell = function (mode) {
+ // mode = shift, ctrl, alt
+ mode = mode || 'shift'
var that = this;
var cell = that.get_selected_cell();
var cell_index = that.find_cell_index(cell);
- if (cell instanceof IPython.CodeCell) {
- cell.execute();
- }
- if (default_options.terminal) {
- cell.select_all();
- } else {
- if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
+
+ cell.execute();
+ console.log('Notebook.execute_selected_cell', mode);
+ if (mode === 'shift') {
+ if (cell_index === (that.ncells()-1)) {
that.insert_cell_below('code');
- // If we are adding a new cell at the end, scroll down to show it.
+ that.select(cell_index+1);
+ that.edit_mode();
that.scroll_to_bottom();
} else {
- that.select(cell_index+1);
- };
- };
+ that.command_mode();
+ }
+ } else if (mode === 'ctrl') {
+ that.select(cell_index+1);
+ that.get_cell(cell_index+1).focus_cell();
+ } else if (mode === 'alt') {
+ // Only insert a new cell, if we ended up in an already populated cell
+ if (/\S/.test(that.get_next_cell().get_text()) == true) {
+ that.insert_cell_below('code');
+ }
+ var next_index = cell_index+1;
+ that.select(cell_index+1);
+ that.edit_mode();
+ }
+
this.set_dirty(true);
};
+
/**
* Execute all cells below the selected cell.
*
@@ -1909,9 +1976,13 @@ var IPython = (function (IPython) {
this.fromJSON(data);
if (this.ncells() === 0) {
this.insert_cell_below('code');
+ this.select(0);
+ this.edit_mode();
+ } else {
+ this.select(0);
+ this.command_mode();
};
this.set_dirty(false);
- this.select(0);
this.scroll_to_top();
if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
var msg = "This notebook has been converted from an older " +
diff --git a/IPython/html/static/notebook/js/textcell.js b/IPython/html/static/notebook/js/textcell.js
index e8cbd35..3c50fde 100644
--- a/IPython/html/static/notebook/js/textcell.js
+++ b/IPython/html/static/notebook/js/textcell.js
@@ -64,7 +64,6 @@ var IPython = (function (IPython) {
};
-
/**
* Create the DOM element of the TextCell
* @method create_element
@@ -101,6 +100,8 @@ var IPython = (function (IPython) {
TextCell.prototype.bind_events = function () {
IPython.Cell.prototype.bind_events.apply(this);
var that = this;
+
+ // TODO: move this to the notebook event handler
this.element.keydown(function (event) {
if (event.which === 13 && !event.shiftKey) {
if (that.rendered) {
@@ -109,11 +110,13 @@ var IPython = (function (IPython) {
};
};
});
+
this.element.dblclick(function () {
that.unrender();
});
};
+
/**
* This method gets called in CodeMirror's onKeyDown/onKeyPress
* handlers and is used to provide custom key handling.
@@ -126,38 +129,34 @@ var IPython = (function (IPython) {
* @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise
*/
TextCell.prototype.handle_codemirror_keyevent = function (editor, event) {
-
- if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
- // Always ignore shift-enter in CodeMirror as we handle it.
- return true;
- }
+ if (this.mode === 'command') {
+ return false
+ } else if (this.mode === 'edit') {
+ if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
+ // Always ignore shift-enter in CodeMirror as we handle it.
+ return true;
+ };
+ return false;
+ };
return false;
};
// Cell level actions
TextCell.prototype.select = function () {
- var continue = IPython.Cell.prototype.select.apply(this);
- if (continue) {
+ var cont = IPython.Cell.prototype.select.apply(this);
+ if (cont) {
if (this.mode === 'edit') {
this.code_mirror.refresh();
}
};
- return continue;
- };
-
- TextCell.prototype.render = function () {
- var continue = IPython.Cell.prototype.render.apply(this);
- if (continue) {
- this.execute();
- };
- return continue;
+ return cont;
};
TextCell.prototype.unrender = function () {
if (this.read_only) return;
- var continue = IPython.Cell.prototype.unrender.apply(this);
- if (continue) {
+ var cont = IPython.Cell.prototype.unrender.apply(this);
+ if (cont) {
var text_cell = this.element;
var output = text_cell.find("div.text_cell_render");
output.hide();
@@ -169,23 +168,27 @@ var IPython = (function (IPython) {
}
};
- return continue;
+ return cont;
+ };
+
+ TextCell.prototype.execute = function () {
+ this.render();
};
TextCell.prototype.command_mode = function () {
- var continue = IPython.Cell.prototype.command_mode.apply(this);
- if (continue) {
+ var cont = IPython.Cell.prototype.command_mode.apply(this);
+ if (cont) {
this.focus_cell();
};
- return continue;
+ return cont;
}
TextCell.prototype.edit_mode = function () {
- var continue = IPython.Cell.prototype.edit_mode.apply(this);
- if (continue) {
+ var cont = IPython.Cell.prototype.edit_mode.apply(this);
+ if (cont) {
this.focus_editor();
};
- return continue;
+ return cont;
}
/**
@@ -224,36 +227,51 @@ var IPython = (function (IPython) {
};
/**
- * not deprecated, but implementation wrong
* @method at_top
- * @deprecated
- * @return {Boolean} true is cell rendered, false otherwise
- * I doubt this is what it is supposed to do
- * this implementation is completly false
+ * @return {Boolean}
*/
TextCell.prototype.at_top = function () {
if (this.rendered) {
return true;
} else {
- return false;
- }
+ if (cursor.line === 0 && cursor.ch === 0) {
+ return true;
+ } else {
+ return false;
+ };
+ };
};
+ /** @method at_bottom **/
+ TextCell.prototype.at_bottom = function () {
+ if (this.rendered) {
+ return true
+ } else {
+ var cursor = this.code_mirror.getCursor();
+ if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
+ return true;
+ } else {
+ return false;
+ };
+ };
+ };
+
/**
- * not deprecated, but implementation wrong
* @method at_bottom
- * @deprecated
- * @return {Boolean} true is cell rendered, false otherwise
- * I doubt this is what it is supposed to do
- * this implementation is completly false
+ * @return {Boolean}
* */
TextCell.prototype.at_bottom = function () {
if (this.rendered) {
return true;
} else {
- return false;
- }
+ var cursor = this.code_mirror.getCursor();
+ if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
+ return true;
+ } else {
+ return false;
+ };
+ };
};
/**
@@ -308,16 +326,14 @@ var IPython = (function (IPython) {
placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$"
}
-
-
-
MarkdownCell.prototype = new TextCell();
/**
* @method render
*/
MarkdownCell.prototype.render = function () {
- if (this.rendered === false) {
+ var cont = IPython.TextCell.prototype.render.apply(this);
+ if (cont) {
var text = this.get_text();
var math = null;
if (text === "") { text = this.placeholder; }
@@ -339,9 +355,9 @@ var IPython = (function (IPython) {
}
this.element.find('div.text_cell_input').hide();
this.element.find("div.text_cell_render").show();
- this.typeset();
- this.rendered = true;
- }
+ this.typeset()
+ };
+ return cont;
};
@@ -357,11 +373,6 @@ var IPython = (function (IPython) {
this.cell_type = 'raw';
TextCell.apply(this, [options]);
-
- var that = this;
- this.element.focusout(
- function() { that.auto_highlight(); }
- );
};
RawCell.options_default = {
@@ -370,10 +381,17 @@ var IPython = (function (IPython) {
"When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
};
-
-
RawCell.prototype = new TextCell();
+ /** @method bind_events **/
+ RawCell.prototype.bind_events = function () {
+ TextCell.prototype.bind_events.apply(this);
+ var that = this
+ this.element.focusout(function() {
+ that.auto_highlight();
+ });
+ };
+
/**
* Trigger autodetection of highlight scheme for current cell
* @method auto_highlight
@@ -384,12 +402,13 @@ var IPython = (function (IPython) {
/** @method render **/
RawCell.prototype.render = function () {
-
- this.rendered = true;
+ // Make sure that this cell type can never be rendered
+ if (this.rendered) {
+ this.unrender();
+ }
var text = this.get_text();
if (text === "") { text = this.placeholder; }
this.set_text(text);
- this.unrender();
};
@@ -397,55 +416,34 @@ var IPython = (function (IPython) {
RawCell.prototype.handle_codemirror_keyevent = function (editor, event) {
var that = this;
- if (event.which === key.UPARROW && event.type === 'keydown') {
- // If we are not at the top, let CM handle the up arrow and
- // prevent the global keydown handler from handling it.
- if (!that.at_top()) {
- event.stop();
- return false;
- } else {
- return true;
- };
- } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
- // If we are not at the bottom, let CM handle the down arrow and
- // prevent the global keydown handler from handling it.
- if (!that.at_bottom()) {
- event.stop();
- return false;
- } else {
- return true;
+ if (this.mode === 'command') {
+ return false
+ } else if (this.mode === 'edit') {
+ // TODO: review these handlers...
+ if (event.which === key.UPARROW && event.type === 'keydown') {
+ // If we are not at the top, let CM handle the up arrow and
+ // prevent the global keydown handler from handling it.
+ if (!that.at_top()) {
+ event.stop();
+ return false;
+ } else {
+ return true;
+ };
+ } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
+ // If we are not at the bottom, let CM handle the down arrow and
+ // prevent the global keydown handler from handling it.
+ if (!that.at_bottom()) {
+ event.stop();
+ return false;
+ } else {
+ return true;
+ };
};
+ return false;
};
return false;
};
- /** @method select **/
- RawCell.prototype.select = function () {
- IPython.Cell.prototype.select.apply(this);
- this.edit();
- };
-
- /** @method at_top **/
- RawCell.prototype.at_top = function () {
- var cursor = this.code_mirror.getCursor();
- if (cursor.line === 0 && cursor.ch === 0) {
- return true;
- } else {
- return false;
- }
- };
-
-
- /** @method at_bottom **/
- RawCell.prototype.at_bottom = function () {
- var cursor = this.code_mirror.getCursor();
- if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
- return true;
- } else {
- return false;
- }
- };
-
/**
* @class HeadingCell
@@ -541,7 +539,8 @@ var IPython = (function (IPython) {
HeadingCell.prototype.render = function () {
- if (this.rendered === false) {
+ var cont = IPython.TextCell.prototype.render.apply(this);
+ if (cont) {
var text = this.get_text();
var math = null;
// Markdown headings must be a single line
@@ -567,8 +566,9 @@ var IPython = (function (IPython) {
this.typeset();
this.element.find('div.text_cell_input').hide();
this.element.find("div.text_cell_render").show();
- this.rendered = true;
+
};
+ return cont;
};
IPython.TextCell = TextCell;
diff --git a/IPython/html/static/notebook/less/cell.less b/IPython/html/static/notebook/less/cell.less
index 0cf8078..ed279f4 100644
--- a/IPython/html/static/notebook/less/cell.less
+++ b/IPython/html/static/notebook/less/cell.less
@@ -6,6 +6,14 @@ div.cell {
.corner-all;
border : thin @border_color solid;
}
+
+ &.edit_mode {
+ .corner-all;
+ border : thin green solid;
+ }
+}
+
+div.cell {
width: 100%;
padding: 5px 5px 5px 0px;
/* This acts as a spacer between cells, that is outside the border */
diff --git a/IPython/html/static/style/ipython.min.css b/IPython/html/static/style/ipython.min.css
index a26bd1f..7d7e790 100644
--- a/IPython/html/static/style/ipython.min.css
+++ b/IPython/html/static/style/ipython.min.css
@@ -54,7 +54,9 @@ input.engine_num_input{height:20px;margin-bottom:2px;padding-top:0;padding-botto
.ansibgpurple{background-color:magenta;}
.ansibgcyan{background-color:cyan;}
.ansibggray{background-color:gray;}
-div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
+div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
+div.cell.edit_mode{border-radius:4px;border:thin green solid;}
+div.cell{width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}
div.prompt{min-width:11ex;padding:0.4em;margin:0px;font-family:monospace;text-align:right;line-height:1.231em;}
div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
div.prompt:empty{padding-top:0;padding-bottom:0;}
diff --git a/IPython/html/static/style/style.min.css b/IPython/html/static/style/style.min.css
index 19f14f5..88d3332 100644
--- a/IPython/html/static/style/style.min.css
+++ b/IPython/html/static/style/style.min.css
@@ -1435,7 +1435,9 @@ input.engine_num_input{height:20px;margin-bottom:2px;padding-top:0;padding-botto
.ansibgpurple{background-color:magenta;}
.ansibgcyan{background-color:cyan;}
.ansibggray{background-color:gray;}
-div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
+div.cell{border:1px solid transparent;display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;}div.cell.selected{border-radius:4px;border:thin #ababab solid;}
+div.cell.edit_mode{border-radius:4px;border:thin green solid;}
+div.cell{width:100%;padding:5px 5px 5px 0px;margin:0px;outline:none;}
div.prompt{min-width:11ex;padding:0.4em;margin:0px;font-family:monospace;text-align:right;line-height:1.231em;}
div.inner_cell{display:-webkit-box;-webkit-box-orient:vertical;-webkit-box-align:stretch;display:-moz-box;-moz-box-orient:vertical;-moz-box-align:stretch;display:box;box-orient:vertical;box-align:stretch;width:100%;-webkit-box-flex:1;-moz-box-flex:1;box-flex:1;}
div.prompt:empty{padding-top:0;padding-bottom:0;}