Lots of updates and changes.

* Cleaning up the code mirror event handlers.
* Adding logic to prevent calling Notebook.command_mode on cell
  focusout.
* Fixing bugs.
Brian E. Granger 13 years ago
parent caffba142e
commit c1166ea98a

@ -120,8 +120,37 @@ var IPython = (function (IPython) {
};
});
that.element.focusout(function (event) {
var is_or_has = function (a, b) {
// Is b a child of a or a itself?
return a.has(b).length !==0 || a.is(b);
}
if (that.mode === 'edit') {
$([IPython.events]).trigger('command_mode.Cell', {'cell':that});
setTimeout(function () {
var trigger = true;
var target = $(document.activeElement);
var completer = that.element.find($('div.completions'));
var tooltip = $('div#tooltip')
if (target.length > 0) {
// If the focused element (target) is inside the cell
// (that.element) don't enter command mode.
if (is_or_has(that.element, target)) {
trigger = false;
// The focused element is outside the cell
} else {
// If the focused element is the tooltip or completer
// don't enter command mode, otherwise do.
trigger = true;
if (tooltip.length > 0 && is_or_has(tooltip, target)) {
trigger = false;
} else if (completer.length > 0 && is_or_has(completer, target)) {
trigger = false;
}
}
}
if (trigger) {
$([IPython.events]).trigger('command_mode.Cell', {'cell':that});
}
}, 1);
};
});
if (this.code_mirror) {

@ -74,7 +74,7 @@ var IPython = (function (IPython) {
var cm_overwrite_options = {
onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
onKeyEvent: $.proxy(this.handle_keyevent,this)
};
options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options});
@ -149,6 +149,17 @@ var IPython = (function (IPython) {
);
};
CodeCell.prototype.handle_keyevent = function (editor, event) {
console.log('CM', this.mode, event.which, event.type)
if (this.mode === 'command') {
return true;
} else if (this.mode === 'edit') {
return this.handle_codemirror_keyevent(editor, event);
}
};
/**
* This method gets called in CodeMirror's onKeyDown/onKeyPress
* handlers and is used to provide custom key handling. Its return
@ -157,61 +168,55 @@ var IPython = (function (IPython) {
* @method handle_codemirror_keyevent
*/
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();
}
if (this.mode === 'command') {
return true;
} 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();
}
var cur = editor.getCursor();
if (event.keyCode === key.ENTER){
this.auto_highlight();
}
if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey || event.altKey)) {
// Always ignore shift-enter in CodeMirror as we handle it.
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 {
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 {
return true;
};
} else if (event.which === key.ESC) {
IPython.tooltip.remove_and_cancel_tooltip(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 {
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;
};
} 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.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);
@ -229,16 +234,18 @@ var IPython = (function (IPython) {
// is empty. In this case, let CodeMirror handle indentation.
return false;
} else {
// keypress/keyup also trigger on TAB press, and we don't want to
// use those to disable tab completion.
return false;
};
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.
return false;
}
return false;
};
// Kernel related calls.
CodeCell.prototype.set_kernel = function (kernel) {

@ -244,28 +244,24 @@ var IPython = (function (IPython) {
//build the container
var that = this;
// this.sel.dblclick(function () {
// that.pick();
// });
// this.sel.blur(this.close);
// this.sel.keydown(function (event) {
// that.keydown(event);
// });
this.sel.dblclick(function () {
that.pick();
});
this.sel.blur(this.close);
this.sel.keydown(function (event) {
that.keydown(event);
});
this.build_gui_list(this.raw_result);
setTimeout(function () {
console.log('doing it');
that.sel.focus();
}, 100);
// this.sel.focus();
this.sel.focus();
// This needs to be after the focus() call because that puts the notebook into
// command mode.
// IPython.keyboard_manager.null_mode();
IPython.keyboard_manager.null_mode();
// Opera sometimes ignores focusing a freshly created node
// if (window.opera) setTimeout(function () {
// if (!this.done) this.sel.focus();
// }, 100);
if (window.opera) setTimeout(function () {
if (!this.done) this.sel.focus();
}, 100);
return true;
}
@ -286,7 +282,6 @@ var IPython = (function (IPython) {
if (this.done) return;
this.done = true;
$('.completions').remove();
console.log('closing...')
IPython.keyboard_manager.edit_mode();
}
@ -301,7 +296,6 @@ var IPython = (function (IPython) {
Completer.prototype.keydown = function (event) {
console.log('keydown', event.keyCode);
var code = event.keyCode;
var that = this;
var special_key = false;

@ -15,8 +15,8 @@ var IPython = (function (IPython) {
var key = IPython.utils.keycodes;
var KeyboardManager = function () {
this.mode = 'null';
this.last_mode = 'null';
this.mode = 'command';
this.last_mode = 'command';
this.bind_events();
};
@ -30,7 +30,7 @@ var IPython = (function (IPython) {
KeyboardManager.prototype.handle_keydown = function (event) {
var notebook = IPython.notebook;
console.log('keyboard_manager', this.mode, event);
console.log('keyboard_manager', this.mode, event.keyCode);
if (event.which === key.ESC) {
// Intercept escape at highest level to avoid closing
@ -39,7 +39,7 @@ var IPython = (function (IPython) {
}
if (this.mode === 'null') {
return this.handle_edit_mode(event);
return this.handle_null_mode(event);
}
// Event handlers for both command and edit mode
@ -252,16 +252,19 @@ var IPython = (function (IPython) {
};
KeyboardManager.prototype.edit_mode = function () {
console.log('KeyboardManager', 'changing to edit mode');
this.last_mode = this.mode;
this.mode = 'edit';
}
KeyboardManager.prototype.command_mode = function () {
console.log('KeyboardManager', 'changing to command mode');
this.last_mode = this.mode;
this.mode = 'command';
}
KeyboardManager.prototype.null_mode = function () {
console.log('KeyboardManager', 'changing to null mode');
this.last_mode = this.mode;
this.mode = 'null';
}

@ -38,6 +38,8 @@ var IPython = (function (IPython) {
this.undelete_index = null;
this.undelete_below = false;
this.paste_enabled = false;
// It is important to start out in command mode to match the intial mode
// of the KeyboardManager.
this.mode = 'command';
this.set_dirty(false);
this.metadata = {};
@ -521,27 +523,27 @@ var IPython = (function (IPython) {
Notebook.prototype.command_mode = function () {
if (this.mode !== 'command') {
console.log('\nNotebook', 'changing to command mode');
var index = this.get_edit_index();
var cell = this.get_cell(index);
if (cell) {
cell.command_mode();
this.mode = 'command';
};
this.mode = 'command';
IPython.keyboard_manager.command_mode();
};
IPython.keyboard_manager.command_mode();
};
Notebook.prototype.edit_mode = function () {
if (this.mode !== 'edit') {
// We are in command mode so get_edit_index() is null!!!
var index = this.get_selected_index();
if (index === null) {return;} // No cell is selected
var cell = this.get_cell(index);
if (cell) {
cell.edit_mode();
this.mode = 'edit';
};
console.log('\nNotebook', 'changing to edit mode');
var cell = this.get_selected_cell();
if (cell === null) {return;} // No cell is selected
// We need to set the mode to edit to prevent reentering this method
// when cell.edit_mode() is called below.
this.mode = 'edit';
IPython.keyboard_manager.edit_mode();
cell.edit_mode();
};
};

@ -41,7 +41,7 @@ var IPython = (function (IPython) {
// we cannot put this as a class key as it has handle to "this".
var cm_overwrite_options = {
onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
onKeyEvent: $.proxy(this.handle_keyevent,this)
};
options = this.mergeopt(TextCell,options,{cm_config:cm_overwrite_options});
@ -109,6 +109,16 @@ var IPython = (function (IPython) {
});
};
TextCell.prototype.handle_keyevent = function (editor, event) {
console.log('CM', this.mode, event.which, event.type)
if (this.mode === 'command') {
return true;
} else if (this.mode === 'edit') {
return this.handle_codemirror_keyevent(editor, event);
}
};
/**
* This method gets called in CodeMirror's onKeyDown/onKeyPress
@ -123,33 +133,29 @@ var IPython = (function (IPython) {
*/
TextCell.prototype.handle_codemirror_keyevent = function (editor, event) {
var that = this;
if (this.mode === 'command') {
return false
} else if (this.mode === 'edit') {
if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey || event.altKey)) {
// Always ignore shift-enter in CodeMirror as we handle it.
if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey || event.altKey)) {
// Always ignore shift-enter in CodeMirror as we handle it.
return 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.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;
};
};
} 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;
};

Loading…
Cancel
Save