diff --git a/IPython/html/static/notebook/js/cell.js b/IPython/html/static/notebook/js/cell.js
index 2a65e4f..7d8506a 100644
--- a/IPython/html/static/notebook/js/cell.js
+++ b/IPython/html/static/notebook/js/cell.js
@@ -39,7 +39,8 @@ var IPython = (function (IPython) {
this.placeholder = options.placeholder || '';
this.read_only = options.cm_config.readOnly;
this.selected = false;
- this.focused = false;
+ this.rendered = false;
+ this.mode = 'command';
this.metadata = {};
// load this from metadata later ?
this.user_highlight = 'auto';
@@ -130,49 +131,126 @@ var IPython = (function (IPython) {
* @method typeset
*/
Cell.prototype.typeset = function () {
- if (window.MathJax){
+ if (window.MathJax) {
var cell_math = this.element.get(0);
MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]);
- }
+ };
};
/**
* handle cell level logic when a cell is selected
* @method select
+ * @return is the action being taken
*/
Cell.prototype.select = function () {
- this.element.addClass('selected');
- this.selected = true;
+ if (!this.selected) {
+ this.element.addClass('selected');
+ this.element.removeClass('unselected');
+ this.selected = true;
+ return true;
+ } else {
+ return false;
+ };
};
/**
* handle cell level logic when a cell is unselected
* @method unselect
+ * @return is the action being taken
*/
Cell.prototype.unselect = function () {
- this.element.removeClass('selected');
- this.selected = false;
+ if (this.selected) {
+ this.element.addClass('unselected');
+ this.element.removeClass('selected');
+ this.selected = false;
+ return true;
+ } else {
+ return false;
+ };
};
/**
- * handle cell level logic when a cell is focused
- * @method focus
+ * handle cell level logic when a cell is rendered
+ * @method render
+ * @return is the action being taken
*/
- Cell.prototype.focus = function () {
- this.element.addClass('focused');
- this.focused = true;
+ Cell.prototype.render = function () {
+ if (!this.rendered) {
+ this.element.addClass('rendered');
+ this.element.removeClass('unrendered');
+ this.rendered = true;
+ return true;
+ } else {
+ return false;
+ };
};
/**
- * handle cell level logic when a cell is unfocused
- * @method unfocus
+ * handle cell level logic when a cell is unrendered
+ * @method unrender
+ * @return is the action being taken
*/
- Cell.prototype.unfocus = function () {
- this.element.removeClass('focused');
- this.focused = false;
+ Cell.prototype.unrender = function () {
+ if (this.rendered) {
+ this.element.addClass('unrendered');
+ this.element.removeClass('rendered');
+ this.rendered = false;
+ return true;
+ } else {
+ return false;
+ };
};
/**
+ * enter the command mode for the cell
+ * @method command_mode
+ * @return is the action being taken
+ */
+ Cell.prototype.command_mode = function () {
+ if (this.mode !== 'command') {
+ this.element.addClass('command_mode');
+ this.element.removeClass('edit_mode');
+ this.mode = 'command';
+ return true;
+ } else {
+ return false;
+ };
+ };
+
+ /**
+ * enter the edit mode for the cell
+ * @method command_mode
+ * @return is the action being taken
+ */
+ Cell.prototype.edit_mode = function () {
+ if (this.mode !== 'edit') {
+ this.element.addClass('edit_mode');
+ this.element.removeClass('command_mode');
+ this.mode = 'edit';
+ return true;
+ } else {
+ return false;
+ };
+ }
+
+ /**
+ * Focus the cell in the DOM sense
+ * @method focus_cell
+ */
+ Cell.prototype.focus_cell = function () {
+ this.element.focus();
+ }
+
+ /**
+ * Focus the editor area so a user can type
+ * @method focus_editor
+ */
+ Cell.prototype.focus_editor = function () {
+ this.code_mirror.refresh();
+ this.code_mirror.focus();
+ }
+
+ /**
* should be overritten by subclass
* @method get_text
*/
diff --git a/IPython/html/static/notebook/js/codecell.js b/IPython/html/static/notebook/js/codecell.js
index bd5c711..9069279 100644
--- a/IPython/html/static/notebook/js/codecell.js
+++ b/IPython/html/static/notebook/js/codecell.js
@@ -149,53 +149,60 @@ var IPython = (function (IPython) {
CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
var that = this;
- // whatever key is pressed, first, cancel the tooltip request before
- // they are sent, and remove tooltip if any, except for tab again
- if (event.type === 'keydown' && event.which != key.TAB ) {
- IPython.tooltip.remove_and_cancel_tooltip();
- }
- var cur = editor.getCursor();
- if (event.keyCode === key.ENTER){
- this.auto_highlight();
- }
+ if (this.mode === 'command') {
+ return false
+ } else if (this.mode === 'edit') {
+ // whatever key is pressed, first, cancel the tooltip request before
+ // they are sent, and remove tooltip if any, except for tab again
+ if (event.type === 'keydown' && event.which != key.TAB ) {
+ IPython.tooltip.remove_and_cancel_tooltip();
+ };
+
+ var cur = editor.getCursor();
+ if (event.keyCode === key.ENTER){
+ this.auto_highlight();
+ }
- if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
- // Always ignore shift-enter in CodeMirror as we handle it.
- return true;
- } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
- // triger on keypress (!) otherwise inconsistent event.which depending on plateform
- // browser and keyboard layout !
- // Pressing '(' , request tooltip, don't forget to reappend it
- // The second argument says to hide the tooltip if the docstring
- // is actually empty
- IPython.tooltip.pending(that, true);
- } else 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 {
+ if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
+ // Always ignore shift-enter in CodeMirror as we handle it.
return true;
- }
- } else if (event.which === key.ESC) {
- return IPython.tooltip.remove_and_cancel_tooltip(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 {
+
+ } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
+ // triger on keypress (!) otherwise inconsistent event.which depending on plateform
+ // browser and keyboard layout !
+ // Pressing '(' , request tooltip, don't forget to reappend it
+ // The second argument says to hide the tooltip if the docstring
+ // is actually empty
+ IPython.tooltip.pending(that, true);
+ } else 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.ESC) {
+ IPython.tooltip.remove_and_cancel_tooltip(true);
return true;
- }
- } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
- if (editor.somethingSelected()){
- var anchor = editor.getCursor("anchor");
- var head = editor.getCursor("head");
- if( anchor.line != head.line){
- return false;
+ } 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;
+ };
+ } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
+ if (editor.somethingSelected()){
+ var anchor = editor.getCursor("anchor");
+ var head = editor.getCursor("head");
+ if( anchor.line != head.line){
+ return false;
+ }
}
}
IPython.tooltip.request(that);
@@ -213,13 +220,10 @@ var IPython = (function (IPython) {
// is empty. In this case, let CodeMirror handle indentation.
return false;
} else {
- event.stop();
- this.completer.startCompletion();
- return true;
- }
- } else {
- // keypress/keyup also trigger on TAB press, and we don't want to
- // use those to disable tab completion.
+ // keypress/keyup also trigger on TAB press, and we don't want to
+ // use those to disable tab completion.
+ return false;
+ };
return false;
}
return false;
@@ -304,21 +308,46 @@ var IPython = (function (IPython) {
// Basic cell manipulation.
CodeCell.prototype.select = function () {
- IPython.Cell.prototype.select.apply(this);
- this.code_mirror.refresh();
- this.auto_highlight();
+ var continue = IPython.Cell.prototype.select.apply(this);
+ if (continue) {
+ this.code_mirror.refresh();
+ this.auto_highlight();
+ };
+ return continue;
};
- CodeCell.prototype.focus = function () {
- IPython.Cell.prototype.focus.apply(this);
- this.code_mirror.focus();
+ CodeCell.prototype.render = function () {
+ var continue = IPython.Cell.prototype.render.apply(this);
+ if (continue) {
+ this.execute();
+ };
+ return continue;
};
- CodeCell.prototype.unfocus = function () {
- IPython.Cell.prototype.focus.apply(this);
- this.code_mirror.blur();
+ CodeCell.prototype.unrender = function () {
+ var continue = IPython.Cell.prototype.unrender.apply(this);
+ if (continue) {
+ this.clear_output(true, true, true);
+ };
+ return continue;
};
+ CodeCell.prototype.command_mode = function () {
+ var continue = IPython.Cell.prototype.command_mode.apply(this);
+ if (continue) {
+ this.focus_cell();
+ };
+ return continue;
+ }
+
+ CodeCell.prototype.edit_mode = function () {
+ var continue = IPython.Cell.prototype.edit_mode.apply(this);
+ if (continue) {
+ this.focus_editor();
+ };
+ return continue;
+ }
+
CodeCell.prototype.select_all = function () {
var start = {line: 0, ch: 0};
var nlines = this.code_mirror.lineCount();
diff --git a/IPython/html/static/notebook/js/notebook.js b/IPython/html/static/notebook/js/notebook.js
index e396b12..3eebb2f 100644
--- a/IPython/html/static/notebook/js/notebook.js
+++ b/IPython/html/static/notebook/js/notebook.js
@@ -946,7 +946,7 @@ var IPython = (function (IPython) {
text = '';
};
// The edit must come before the set_text.
- target_cell.edit();
+ target_cell.unrender();
target_cell.set_text(text);
// make this value the starting point, so that we can only undo
// to this state, instead of a blank cell
@@ -976,7 +976,7 @@ var IPython = (function (IPython) {
text = '';
};
// The edit must come before the set_text.
- target_cell.edit();
+ target_cell.unrender();
target_cell.set_text(text);
// make this value the starting point, so that we can only undo
// to this state, instead of a blank cell
@@ -1011,7 +1011,7 @@ var IPython = (function (IPython) {
};
// The edit must come before the set_text.
target_cell.set_level(level);
- target_cell.edit();
+ target_cell.unrender();
target_cell.set_text(text);
// make this value the starting point, so that we can only undo
// to this state, instead of a blank cell
@@ -1179,7 +1179,7 @@ var IPython = (function (IPython) {
cell.set_text(textb);
cell.render();
var new_cell = this.insert_cell_above('markdown');
- new_cell.edit(); // editor must be visible to call set_text
+ new_cell.unrender(); // editor must be visible to call set_text
new_cell.set_text(texta);
new_cell.render();
this.select_next();
@@ -1208,7 +1208,7 @@ var IPython = (function (IPython) {
if (cell instanceof IPython.CodeCell) {
cell.set_text(upper_text+'\n'+text);
} else if (cell instanceof IPython.MarkdownCell) {
- cell.edit();
+ cell.unrender();
cell.set_text(upper_text+'\n'+text);
cell.render();
};
@@ -1238,7 +1238,7 @@ var IPython = (function (IPython) {
if (cell instanceof IPython.CodeCell) {
cell.set_text(text+'\n'+lower_text);
} else if (cell instanceof IPython.MarkdownCell) {
- cell.edit();
+ cell.unrender();
cell.set_text(text+'\n'+lower_text);
cell.render();
};
diff --git a/IPython/html/static/notebook/js/textcell.js b/IPython/html/static/notebook/js/textcell.js
index cf7f003..e8cbd35 100644
--- a/IPython/html/static/notebook/js/textcell.js
+++ b/IPython/html/static/notebook/js/textcell.js
@@ -104,13 +104,13 @@ var IPython = (function (IPython) {
this.element.keydown(function (event) {
if (event.which === 13 && !event.shiftKey) {
if (that.rendered) {
- that.edit();
+ that.unrender();
return false;
};
};
});
this.element.dblclick(function () {
- that.edit();
+ that.unrender();
});
};
@@ -134,57 +134,59 @@ var IPython = (function (IPython) {
return false;
};
- /**
- * Select the current cell and trigger 'focus'
- * @method select
- */
+ // Cell level actions
+
TextCell.prototype.select = function () {
- IPython.Cell.prototype.select.apply(this);
- var output = this.element.find("div.text_cell_render");
- output.trigger('focus');
+ var continue = IPython.Cell.prototype.select.apply(this);
+ if (continue) {
+ if (this.mode === 'edit') {
+ this.code_mirror.refresh();
+ }
+ };
+ return continue;
};
- /**
- * unselect the current cell and `render` it
- * @method unselect
- */
- TextCell.prototype.unselect = function() {
- // render on selection of another cell
- this.render();
- IPython.Cell.prototype.unselect.apply(this);
+ TextCell.prototype.render = function () {
+ var continue = IPython.Cell.prototype.render.apply(this);
+ if (continue) {
+ this.execute();
+ };
+ return continue;
};
- /**
- *
- * put the current cell in edition mode
- * @method edit
- */
- TextCell.prototype.edit = function () {
- if (this.rendered === true) {
+ TextCell.prototype.unrender = function () {
+ if (this.read_only) return;
+ var continue = IPython.Cell.prototype.unrender.apply(this);
+ if (continue) {
var text_cell = this.element;
var output = text_cell.find("div.text_cell_render");
output.hide();
text_cell.find('div.text_cell_input').show();
- this.code_mirror.refresh();
- this.code_mirror.focus();
- // We used to need an additional refresh() after the focus, but
- // it appears that this has been fixed in CM. This bug would show
- // up on FF when a newly loaded markdown cell was edited.
- this.rendered = false;
+ this.focus_editor();
if (this.get_text() === this.placeholder) {
this.set_text('');
this.refresh();
}
- }
- };
+ };
+ return continue;
+ };
- /**
- * Empty, Subclasses must define render.
- * @method render
- */
- TextCell.prototype.render = function () {};
+ TextCell.prototype.command_mode = function () {
+ var continue = IPython.Cell.prototype.command_mode.apply(this);
+ if (continue) {
+ this.focus_cell();
+ };
+ return continue;
+ }
+ TextCell.prototype.edit_mode = function () {
+ var continue = IPython.Cell.prototype.edit_mode.apply(this);
+ if (continue) {
+ this.focus_editor();
+ };
+ return continue;
+ }
/**
* setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
@@ -382,11 +384,12 @@ var IPython = (function (IPython) {
/** @method render **/
RawCell.prototype.render = function () {
+
this.rendered = true;
var text = this.get_text();
if (text === "") { text = this.placeholder; }
- console.log('rendering', text);
this.set_text(text);
+ this.unrender();
};