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);
+ }
+ });
+ };
};
/**