##// END OF EJS Templates
Merge pull request #5320 from jdfreder/focusbug_tt...
Paul Ivanov -
r15972:0e14026d merge
parent child Browse files
Show More
@@ -147,10 +147,7 b' var IPython = (function (IPython) {'
147 147 }
148 148 if (this.code_mirror) {
149 149 this.code_mirror.on('blur', function(cm, change) {
150 // Check if this unfocus event is legit.
151 if (!that.should_cancel_blur()) {
152 $([IPython.events]).trigger('command_mode.Cell', {cell: that});
153 }
150 $([IPython.events]).trigger('command_mode.Cell', {cell: that});
154 151 });
155 152 }
156 153 };
@@ -331,18 +328,7 b' var IPython = (function (IPython) {'
331 328 return false;
332 329 }
333 330 };
334
335 /**
336 * Determine whether or not the unfocus event should be aknowledged.
337 *
338 * @method should_cancel_blur
339 *
340 * @return results {bool} Whether or not to ignore the cell's blur event.
341 **/
342 Cell.prototype.should_cancel_blur = function () {
343 return false;
344 };
345
331
346 332 /**
347 333 * Focus the cell in the DOM sense
348 334 * @method focus_cell
@@ -358,21 +358,6 b' var IPython = (function (IPython) {'
358 358 return false;
359 359 };
360 360
361 /**
362 * Determine whether or not the unfocus event should be aknowledged.
363 *
364 * @method should_cancel_blur
365 *
366 * @return results {bool} Whether or not to ignore the cell's blur event.
367 **/
368 CodeCell.prototype.should_cancel_blur = function () {
369 // Cancel this unfocus event if the base wants to cancel or the cell
370 // completer is open or the tooltip is open.
371 return IPython.Cell.prototype.should_cancel_blur.apply(this) ||
372 (this.completer && this.completer.is_visible()) ||
373 (IPython.tooltip && IPython.tooltip.is_visible());
374 };
375
376 361 CodeCell.prototype.select_all = function () {
377 362 var start = {line: 0, ch: 0};
378 363 var nlines = this.code_mirror.lineCount();
@@ -508,6 +493,23 b' var IPython = (function (IPython) {'
508 493 return data;
509 494 };
510 495
496 /**
497 * handle cell level logic when a cell is unselected
498 * @method unselect
499 * @return is the action being taken
500 */
501 CodeCell.prototype.unselect = function () {
502 var cont = IPython.Cell.prototype.unselect.apply(this);
503 if (cont) {
504 // When a code cell is usnelected, make sure that the corresponding
505 // tooltip and completer to that cell is closed.
506 IPython.tooltip.remove_and_cancel_tooltip(true);
507 if (this.completer !== null) {
508 this.completer.close();
509 }
510 }
511 return cont;
512 };
511 513
512 514 IPython.CodeCell = CodeCell;
513 515
@@ -73,7 +73,6 b' var IPython = (function (IPython) {'
73 73
74 74
75 75 var Completer = function (cell) {
76 this._visible = false;
77 76 this.cell = cell;
78 77 this.editor = cell.code_mirror;
79 78 var that = this;
@@ -85,15 +84,9 b' var IPython = (function (IPython) {'
85 84 });
86 85 };
87 86
88 Completer.prototype.is_visible = function () {
89 // Return whether or not the completer is visible.
90 return this._visible;
91 };
92
93 87 Completer.prototype.startCompletion = function () {
94 88 // call for a 'first' completion, that will set the editor and do some
95 // special behaviour like autopicking if only one completion availlable
96 //
89 // special behavior like autopicking if only one completion available.
97 90 if (this.editor.somethingSelected()) return;
98 91 this.done = false;
99 92 // use to get focus back on opera
@@ -221,17 +214,37 b' var IPython = (function (IPython) {'
221 214 }
222 215 }
223 216
224 this.complete = $('<div/>').addClass('completions');
225 this.complete.attr('id', 'complete');
226
227 // Currently webkit doesn't use the size attr correctly. See:
228 // https://code.google.com/p/chromium/issues/detail?id=4579
229 this.sel = $('<select style="width: auto"/>')
230 .attr('multiple', 'true')
231 .attr('size', Math.min(10, this.raw_result.length));
232 this.complete.append(this.sel);
233 this._visible = true;
234 $('body').append(this.complete);
217 if (!this.visible) {
218 this.complete = $('<div/>').addClass('completions');
219 this.complete.attr('id', 'complete');
220
221 // Currently webkit doesn't use the size attr correctly. See:
222 // https://code.google.com/p/chromium/issues/detail?id=4579
223 this.sel = $('<select/>')
224 .attr('tabindex', -1)
225 .attr('multiple', 'true');
226 this.complete.append(this.sel);
227 this.visible = true;
228 $('body').append(this.complete);
229
230 //build the container
231 var that = this;
232 this.sel.dblclick(function () {
233 that.pick();
234 });
235 this.sel.focus(function () {
236 that.editor.focus();
237 });
238 this._handle_keydown = function (cm, event) {
239 that.keydown(event);
240 };
241 this.editor.on('keydown', this._handle_keydown);
242 this._handle_keypress = function (cm, event) {
243 that.keypress(event);
244 };
245 this.editor.on('keypress', this._handle_keypress);
246 }
247 this.sel.attr('size', Math.min(10, this.raw_result.length));
235 248
236 249 // After everything is on the page, compute the postion.
237 250 // We put it above the code if it is too close to the bottom of the page.
@@ -249,28 +262,9 b' var IPython = (function (IPython) {'
249 262 this.complete.css('left', left + 'px');
250 263 this.complete.css('top', top + 'px');
251 264
252
253 //build the container
254 var that = this;
255 this.sel.dblclick(function () {
256 that.pick();
257 });
258 this.sel.blur(this.close);
259 this.sel.keydown(function (event) {
260 that.keydown(event);
261 });
262 this.sel.keypress(function (event) {
263 that.keypress(event);
264 });
265
265 // Clear and fill the list.
266 this.sel.text('');
266 267 this.build_gui_list(this.raw_result);
267
268 this.sel.focus();
269 IPython.keyboard_manager.disable();
270 // Opera sometimes ignores focusing a freshly created node
271 if (window.opera) setTimeout(function () {
272 if (!this.done) this.sel.focus();
273 }, 100);
274 268 return true;
275 269 };
276 270
@@ -288,20 +282,16 b' var IPython = (function (IPython) {'
288 282 };
289 283
290 284 Completer.prototype.close = function () {
291 this._visible = false;
292 if (this.done) return;
293 285 this.done = true;
294 $('.completions').remove();
295 IPython.keyboard_manager.enable();
286 $('#complete').remove();
287 this.editor.off('keydown', this._handle_keydown);
288 this.editor.off('keypress', this._handle_keypress);
289 this.visible = false;
296 290 };
297 291
298 292 Completer.prototype.pick = function () {
299 293 this.insert(this.raw_result[this.sel[0].selectedIndex]);
300 294 this.close();
301 var that = this;
302 setTimeout(function () {
303 that.editor.focus();
304 }, 50);
305 295 };
306 296
307 297 Completer.prototype.keydown = function (event) {
@@ -312,16 +302,10 b' var IPython = (function (IPython) {'
312 302 if (code == keycodes.enter) {
313 303 CodeMirror.e_stop(event);
314 304 this.pick();
315 }
316 305 // Escape or backspace
317 else if (code == keycodes.esc) {
306 } else if (code == keycodes.esc || code == keycodes.backspace) {
318 307 CodeMirror.e_stop(event);
319 308 this.close();
320 this.editor.focus();
321
322 } else if (code == keycodes.backspace) {
323 this.close();
324 this.editor.focus();
325 309 } else if (code == keycodes.tab) {
326 310 //all the fastforwarding operation,
327 311 //Check that shared start is not null which can append with prefixed completion
@@ -332,8 +316,6 b' var IPython = (function (IPython) {'
332 316 this.insert(sh);
333 317 }
334 318 this.close();
335 CodeMirror.e_stop(event);
336 this.editor.focus();
337 319 //reinvoke self
338 320 setTimeout(function () {
339 321 that.carry_on_completion();
@@ -341,10 +323,23 b' var IPython = (function (IPython) {'
341 323 } else if (code == keycodes.up || code == keycodes.down) {
342 324 // need to do that to be able to move the arrow
343 325 // when on the first or last line ofo a code cell
344 event.stopPropagation();
326 CodeMirror.e_stop(event);
327
328 var options = this.sel.find('option');
329 var index = this.sel[0].selectedIndex;
330 if (code == keycodes.up) {
331 index--;
332 }
333 if (code == keycodes.down) {
334 index++;
335 }
336 index = Math.min(Math.max(index, 0), options.length-1);
337 this.sel[0].selectedIndex = index;
338 } else if (code == keycodes.left || code == keycodes.right) {
339 this.close();
345 340 }
346 341 };
347
342
348 343 Completer.prototype.keypress = function (event) {
349 344 // FIXME: This is a band-aid.
350 345 // on keypress, trigger insertion of a single character.
@@ -358,26 +353,16 b' var IPython = (function (IPython) {'
358 353 // don't handle keypress if it's not a character (arrows on FF)
359 354 // or ENTER/TAB
360 355 if (event.charCode === 0 ||
361 code == keycodes.enter ||
362 code == keycodes.tab
356 code == keycodes.tab ||
357 code == keycodes.enter
363 358 ) return;
364 359
365 var cur = this.editor.getCursor();
366 var completion = {
367 str: String.fromCharCode(event.which),
368 type: "introspection",
369 from: cur,
370 to: cur,
371 };
372 this.insert(completion);
373
374 360 this.close();
375 361 this.editor.focus();
376 362 setTimeout(function () {
377 363 that.carry_on_completion();
378 364 }, 50);
379 365 };
380
381 366 IPython.Completer = Completer;
382 367
383 368 return IPython;
@@ -17,6 +17,7 b''
17 17 font-family: @monoFontFamily;
18 18 font-size: 110%;
19 19 color: @textColor;
20 width: auto;
20 21 }
21 22
22 23 .completions select option.context {
@@ -1,7 +1,3 b''
1 .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}
2 .clearfix:after{clear:both}
3 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}
4 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
5 1 article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}
6 2 audio,canvas,video{display:inline-block;*display:inline;*zoom:1}
7 3 audio:not([controls]){display:none}
@@ -856,6 +852,10 b' a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decorati'
856 852 .show{display:block}
857 853 .invisible{visibility:hidden}
858 854 .affix{position:fixed}
855 .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0}
856 .clearfix:after{clear:both}
857 .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}
858 .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
859 859 @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}
860 860 .visible-phone{display:none !important}
861 861 .visible-tablet{display:none !important}
@@ -1497,7 +1497,7 b' p{margin-bottom:0}'
1497 1497 .celltoolbar input[type=checkbox]{margin:0;margin-left:4px;margin-right:4px}
1498 1498 .celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px}
1499 1499 .completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0 6px 10px -1px #adadad;-moz-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad}
1500 .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000}
1500 .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000;width:auto}
1501 1501 .completions select option.context{color:#0064cd}
1502 1502 #menubar .navbar-inner{min-height:28px;border-top:1px;border-radius:0 0 4px 4px}
1503 1503 #menubar .navbar{margin-bottom:8px}
General Comments 0
You need to be logged in to leave comments. Login now