From 06aa0d540d562d9e8eec400d0cda26ef5c4b93a2 Mon Sep 17 00:00:00 2001 From: "Brian E. Granger" Date: Sun, 8 Dec 2013 13:36:02 -0800 Subject: [PATCH] Using a more specific approach for managing CM focus. I used to try and enter command mode when a cell looses focus. The problem with that is that focusing an output area would remain in edit mode. Now, I bind this logic to the code mirror blur event, so that focusing the output area enters command mode. --- IPython/html/static/base/js/utils.js | 24 ++++++++++- IPython/html/static/notebook/js/cell.js | 57 ++++++++----------------- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/IPython/html/static/base/js/utils.js b/IPython/html/static/base/js/utils.js index aa4dcbe0d..b3f7b3a18 100644 --- a/IPython/html/static/base/js/utils.js +++ b/IPython/html/static/base/js/utils.js @@ -455,6 +455,26 @@ IPython.utils = (function (IPython) { return M; })(); + 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); + } + + var is_focused = function (e) { + // Is element e, or one of its children focused? + e = $(e); + var target = $(document.activeElement); + if (target.length > 0) { + if (is_or_has(e, target)) { + return true; + } else { + return false; + } + } else { + return false; + } + } + return { regex_split : regex_split, @@ -475,7 +495,9 @@ IPython.utils = (function (IPython) { encode_uri_components : encode_uri_components, splitext : splitext, always_new : always_new, - browser : browser + browser : browser, + is_or_has : is_or_has, + is_focused : is_focused }; }(IPython)); diff --git a/IPython/html/static/notebook/js/cell.js b/IPython/html/static/notebook/js/cell.js index 5813064f7..219d95a02 100644 --- a/IPython/html/static/notebook/js/cell.js +++ b/IPython/html/static/notebook/js/cell.js @@ -110,52 +110,15 @@ var IPython = (function (IPython) { var that = this; // We trigger events so that Cell doesn't have to depend on Notebook. that.element.click(function (event) { - if (that.selected === false) { + if (!that.selected) { $([IPython.events]).trigger('select.Cell', {'cell':that}); }; }); that.element.focusin(function (event) { - if (that.selected === false) { + if (!that.selected) { $([IPython.events]).trigger('select.Cell', {'cell':that}); }; }); - 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') { - // Most of the time, when a cell is in edit mode and focusout - // fires, it means we should enter command mode. But there are cases - // when we should not enter command mode. - setTimeout(function () { - var trigger = true; - var target = $(document.activeElement); - var completer = $('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) { this.code_mirror.on("change", function(cm, change) { $([IPython.events]).trigger("set_dirty.Notebook", {value: true}); @@ -166,6 +129,22 @@ var IPython = (function (IPython) { $([IPython.events]).trigger('edit_mode.Cell', {cell: that}); }); }; + if (this.code_mirror) { + this.code_mirror.on('blur', function(cm, change) { + if (that.mode === 'edit') { + setTimeout(function () { + var isf = IPython.utils.is_focused; + var trigger = true; + if (isf('div#tooltip') || isf('div.completions')) { + trigger = false; + } + if (trigger) { + $([IPython.events]).trigger('command_mode.Cell', {cell: that}); + } + }, 1); + } + }); + }; }; /**