##// END OF EJS Templates
Fixed lots of bugs...
Jonathan Frederic -
Show More
@@ -118,7 +118,7 b' var IPython = (function (IPython) {'
118 } else {
118 } else {
119 this.element.addClass('command_mode');
119 this.element.addClass('command_mode');
120 }
120 }
121 }
121 };
122
122
123
123
124 /**
124 /**
@@ -133,12 +133,12 b' var IPython = (function (IPython) {'
133 that.element.click(function (event) {
133 that.element.click(function (event) {
134 if (!that.selected) {
134 if (!that.selected) {
135 $([IPython.events]).trigger('select.Cell', {'cell':that});
135 $([IPython.events]).trigger('select.Cell', {'cell':that});
136 };
136 }
137 });
137 });
138 that.element.focusin(function (event) {
138 that.element.focusin(function (event) {
139 if (!that.selected) {
139 if (!that.selected) {
140 $([IPython.events]).trigger('select.Cell', {'cell':that});
140 $([IPython.events]).trigger('select.Cell', {'cell':that});
141 };
141 }
142 });
142 });
143 if (this.code_mirror) {
143 if (this.code_mirror) {
144 this.code_mirror.on("change", function(cm, change) {
144 this.code_mirror.on("change", function(cm, change) {
@@ -147,31 +147,12 b' var IPython = (function (IPython) {'
147 }
147 }
148 if (this.code_mirror) {
148 if (this.code_mirror) {
149 this.code_mirror.on('focus', function(cm, change) {
149 this.code_mirror.on('focus', function(cm, change) {
150 console.log('cell focused');
150 $([IPython.events]).trigger('focus_text.Cell', {cell: that});
151 if (that._continue_blur) {
152 that._continue_blur = false;
153 } else {
154 if (that.mode === 'command') {
155 $([IPython.events]).trigger('edit_mode.Cell', {cell: that});
156 }
157 }
158 });
151 });
159 }
152 }
160 if (this.code_mirror) {
153 if (this.code_mirror) {
161 this.code_mirror.on('blur', function(cm, change) {
154 this.code_mirror.on('blur', function(cm, change) {
162 console.log('cell blur');
155 $([IPython.events]).trigger('blur_text.Cell', {cell: that});
163 that._continue_blur = true;
164 setTimeout($.proxy(function () {
165 if (that._continue_blur) {
166 console.log('cell blur> edit true> callback');
167 var isf = IPython.utils.is_focused;
168 if (! (isf('div#tooltip') || isf('div.completions'))) {
169 if (that.mode === 'edit') {
170 $([IPython.events]).trigger('command_mode.Cell', {cell: that});
171 }
172 }
173 }
174 }, that), 1);
175 });
156 });
176 }
157 }
177 };
158 };
@@ -281,7 +262,7 b' var IPython = (function (IPython) {'
281 } else {
262 } else {
282 return false;
263 return false;
283 }
264 }
284 }
265 };
285
266
286 /**
267 /**
287 * Focus the cell in the DOM sense
268 * Focus the cell in the DOM sense
@@ -289,24 +270,7 b' var IPython = (function (IPython) {'
289 */
270 */
290 Cell.prototype.focus_cell = function () {
271 Cell.prototype.focus_cell = function () {
291 this.element.focus();
272 this.element.focus();
292 }
273 };
293
294 /**
295 * Focus the editor area so a user can type
296 * @method focus_editor
297 */
298 Cell.prototype.focus_editor = function () {
299 var that = this;
300 this.refresh();
301 // Only focus the CM editor if it is not focused already. This prevents jumps
302 // related to the previous prompt position.
303 setTimeout(function () {
304 var isf = IPython.utils.is_focused;
305 if (!isf(that.element.find('div.CodeMirror'))) {
306 that.code_mirror.focus();
307 }
308 }, 1);
309 }
310
274
311 /**
275 /**
312 * Refresh codemirror instance
276 * Refresh codemirror instance
@@ -391,6 +391,14 b' var IPython = (function (IPython) {'
391 return cont;
391 return cont;
392 };
392 };
393
393
394 CodeCell.prototype.unselect = function () {
395 var cont = IPython.Cell.prototype.unselect.apply(this);
396 if (cont) {
397 this.code_mirror.getInputField().blur();
398 }
399 return cont;
400 };
401
394 CodeCell.prototype.render = function () {
402 CodeCell.prototype.render = function () {
395 var cont = IPython.Cell.prototype.render.apply(this);
403 var cont = IPython.Cell.prototype.render.apply(this);
396 // Always execute, even if we are already in the rendered state
404 // Always execute, even if we are already in the rendered state
@@ -404,11 +412,27 b' var IPython = (function (IPython) {'
404
412
405 CodeCell.prototype.edit_mode = function () {
413 CodeCell.prototype.edit_mode = function () {
406 var cont = IPython.Cell.prototype.edit_mode.apply(this);
414 var cont = IPython.Cell.prototype.edit_mode.apply(this);
407 if (cont) {
415 if (this.mode === 'edit') {
408 this.focus_editor();
416 this.focus_editor();
409 }
417 }
410 return cont;
418 return cont;
411 }
419 };
420
421 /**
422 * Focus the editor area so a user can type
423 * @method focus_editor
424 */
425 CodeCell.prototype.focus_editor = function () {
426 // Only focus the CM editor if it is not focused already. This prevents
427 // jumps related to the previous prompt position. Here we can't use
428 // IPython.utils.is_focused since it uses document.activeElement which
429 // may not be set by the time this is called. Instead look at the input
430 // element of codemirror directly to see if it is focused. Use the
431 // jQuery :focus pseudo selector (http://api.jquery.com/focus-selector/)
432 if (!$(this.code_mirror.win).is(':focus')) {
433 this.code_mirror.focus();
434 }
435 };
412
436
413 CodeCell.prototype.select_all = function () {
437 CodeCell.prototype.select_all = function () {
414 var start = {line: 0, ch: 0};
438 var start = {line: 0, ch: 0};
@@ -73,6 +73,7 b' var IPython = (function (IPython) {'
73
73
74
74
75 var Completer = function (cell) {
75 var Completer = function (cell) {
76 this._visible = false;
76 this.cell = cell;
77 this.cell = cell;
77 this.editor = cell.code_mirror;
78 this.editor = cell.code_mirror;
78 var that = this;
79 var that = this;
@@ -84,6 +85,10 b' var IPython = (function (IPython) {'
84 });
85 });
85 };
86 };
86
87
88 Completer.prototype.is_visible = function () {
89 // Return whether or not the completer is visible.
90 return this._visible;
91 };
87
92
88 Completer.prototype.startCompletion = function () {
93 Completer.prototype.startCompletion = function () {
89 // call for a 'first' completion, that will set the editor and do some
94 // call for a 'first' completion, that will set the editor and do some
@@ -225,6 +230,7 b' var IPython = (function (IPython) {'
225 .attr('multiple', 'true')
230 .attr('multiple', 'true')
226 .attr('size', Math.min(10, this.raw_result.length));
231 .attr('size', Math.min(10, this.raw_result.length));
227 this.complete.append(this.sel);
232 this.complete.append(this.sel);
233 this._visible = true;
228 $('body').append(this.complete);
234 $('body').append(this.complete);
229
235
230 // After everything is on the page, compute the postion.
236 // After everything is on the page, compute the postion.
@@ -282,6 +288,7 b' var IPython = (function (IPython) {'
282 };
288 };
283
289
284 Completer.prototype.close = function () {
290 Completer.prototype.close = function () {
291 this._visible = false;
285 if (this.done) return;
292 if (this.done) return;
286 this.done = true;
293 this.done = true;
287 $('.completions').remove();
294 $('.completions').remove();
@@ -115,20 +115,12 b' var IPython = (function (IPython) {'
115 that.select(index);
115 that.select(index);
116 });
116 });
117
117
118 $([IPython.events]).on('edit_mode.Cell', function (event, data) {
118 $([IPython.events]).on('focus_text.Cell', function (event, data) {
119 console.log('edit mode cell');
119 that.handle_cell_text_focus(that.find_cell_index(data.cell));
120 var index = that.find_cell_index(data.cell);
121 that.select(index);
122 that.edit_mode();
123 });
120 });
124
121
125 $([IPython.events]).on('command_mode.Cell', function (event, data) {
122 $([IPython.events]).on('blur_text.Cell', function (event, data) {
126 console.log('command mode cell');
123 that.handle_cell_text_blur(that.find_cell_index(data.cell));
127 // In Firefox the focus event is called before the blur event. In
128 // other words, two cells elements may be focused at any given time.
129 // Here we verify that no cells are currently in edit mode before
130 // putting the entire notebook in command mode.
131 that.command_mode();
132 });
124 });
133
125
134 $([IPython.events]).on('status_autorestarting.Kernel', function () {
126 $([IPython.events]).on('status_autorestarting.Kernel', function () {
@@ -465,6 +457,8 b' var IPython = (function (IPython) {'
465 if (this.is_valid_cell_index(index)) {
457 if (this.is_valid_cell_index(index)) {
466 var sindex = this.get_selected_index();
458 var sindex = this.get_selected_index();
467 if (sindex !== null && index !== sindex) {
459 if (sindex !== null && index !== sindex) {
460 // Put the cell in command mode and unselect it.
461 this.get_cell(sindex).command_mode();
468 this.get_cell(sindex).unselect();
462 this.get_cell(sindex).unselect();
469 }
463 }
470 var cell = this.get_cell(index);
464 var cell = this.get_cell(index);
@@ -509,41 +503,67 b' var IPython = (function (IPython) {'
509
503
510 // Edit/Command mode
504 // Edit/Command mode
511
505
512 Notebook.prototype.get_edit_index = function () {
506 Notebook.prototype.get_edit_index = function (ignore_index) {
513 var result = null;
507 var result = null;
514 this.get_cell_elements().filter(function (index) {
508 this.get_cell_elements().filter(function (index) {
515 if ($(this).data("cell").mode === 'edit') {
509 if ($(this).data("cell").mode === 'edit') {
516 result = index;
510 if (ignore_index===undefined || ignore_index!==index) {
511 result = index;
512 }
517 }
513 }
518 });
514 });
519 return result;
515 return result;
520 };
516 };
521
517
522 Notebook.prototype.command_mode = function () {
518 Notebook.prototype.command_mode = function () {
523 console.log('cell.command_mode');
519 console.log('notebook command_mode()');
520
521 // Make sure there isn't an edit mode cell lingering around.
522 var cell = this.get_cell(this.get_edit_index());
523 if (cell) {
524 cell.command_mode();
525 }
526
527 // Notify the keyboard manager if this is a change of mode for the
528 // notebook as a whole.
524 if (this.mode !== 'command') {
529 if (this.mode !== 'command') {
525 $([IPython.events]).trigger('command_mode.Notebook');
526 var index = this.get_edit_index();
527 var cell = this.get_cell(index);
528 if (cell) {
529 cell.command_mode();
530 }
531 this.mode = 'command';
530 this.mode = 'command';
531 $([IPython.events]).trigger('command_mode.Notebook');
532 IPython.keyboard_manager.command_mode();
532 IPython.keyboard_manager.command_mode();
533 }
533 }
534 };
534 };
535
535
536 Notebook.prototype.edit_mode = function () {
536 Notebook.prototype.edit_mode = function (index) {
537 console.log('cell.edit_mode');
537 console.log('notebook edit_mode()');
538
539 // Either use specified index or selected cell's index.
540 // Must explictly check for undefined CBool(0) = false.
541 if (index===undefined) {
542 index = this.get_selected_index();
543 }
544 var cell = this.get_cell(index);
545 // Make sure the cell exists.
546 if (cell === null) { return; }
547
548 // If another cell is currently in edit mode set it to command mode.
549 var edit_index = this.get_edit_index(index);
550 if (edit_index !== null) { // Must explictly check for null CBool(0) = false.
551 var edit_cell = this.get_cell(edit_index);
552 if (edit_cell) {
553 edit_cell.command_mode();
554 }
555 }
556
557 // Set the cell to edit mode and notify the keyboard manager if this
558 // is a change of mode for the notebook as a whole.
559 if (this.get_selected_index()!==index) {
560 this.select(index);
561 }
562 cell.edit_mode();
538 if (this.mode !== 'edit') {
563 if (this.mode !== 'edit') {
539 $([IPython.events]).trigger('edit_mode.Notebook');
540 var cell = this.get_selected_cell();
541 if (cell === null) {return;} // No cell is selected
542 // We need to set the mode to edit to prevent reentering this method
543 // when cell.edit_mode() is called below.
544 this.mode = 'edit';
564 this.mode = 'edit';
565 $([IPython.events]).trigger('edit_mode.Notebook');
545 IPython.keyboard_manager.edit_mode();
566 IPython.keyboard_manager.edit_mode();
546 cell.edit_mode();
547 }
567 }
548 };
568 };
549
569
@@ -553,6 +573,36 b' var IPython = (function (IPython) {'
553 cell.focus_cell();
573 cell.focus_cell();
554 };
574 };
555
575
576 Notebook.prototype.handle_cell_text_focus = function (index) {
577 this.edit_mode(index);
578 };
579
580 Notebook.prototype.handle_cell_text_blur = function (index) {
581 var cell = this.get_cell(index);
582 if (!cell) {return;}
583
584 // Only respect the blur event if the tooltip and autocompleter are
585 // not visible.
586 var tooltip_visible = IPython.tooltip && IPython.tooltip.is_visible();
587 var completer_visible = cell.completer && cell.completer.is_visible();
588 if (!tooltip_visible && !completer_visible) {
589 // In Firefox the focus event is called before the blur event. In
590 // other words, two cells elements may be focused at any given time.
591 // This has been witnessed on Win7 x64 w/ FF 25. Here we only put the
592 // entire notebook in command mode iff the cell textbox being blured is
593 // the one that is currently in edit mode. Otherwise, we assume the
594 // event order has been reversed and we just put this particular cell
595 // in command mode.
596 if (index===this.get_edit_index(index)) {
597 console.log('full command_mode');
598 this.command_mode();
599 } else {
600 console.log('cell command_mode');
601 cell.command_mode();
602 }
603 }
604 };
605
556 // Cell movement
606 // Cell movement
557
607
558 /**
608 /**
@@ -1411,8 +1461,8 b' var IPython = (function (IPython) {'
1411
1461
1412 console.log('execute cell command_mode');
1462 console.log('execute cell command_mode');
1413 cell.execute();
1463 cell.execute();
1414 this.command_mode();
1415 cell.focus_cell();
1464 cell.focus_cell();
1465 this.command_mode();
1416 this.set_dirty(true);
1466 this.set_dirty(true);
1417 };
1467 };
1418
1468
@@ -1467,6 +1517,7 b' var IPython = (function (IPython) {'
1467
1517
1468 this.select(cell_index+1);
1518 this.select(cell_index+1);
1469 this.get_cell(cell_index+1).focus_cell();
1519 this.get_cell(cell_index+1).focus_cell();
1520 this.command_mode();
1470 this.set_dirty(true);
1521 this.set_dirty(true);
1471 };
1522 };
1472
1523
@@ -52,7 +52,7 b' var IPython = (function (IPython) {'
52 // expand the tooltip to see more
52 // expand the tooltip to see more
53 var expandlink = $('<a/>').attr('href', "#").addClass("ui-corner-all") //rounded corner
53 var expandlink = $('<a/>').attr('href', "#").addClass("ui-corner-all") //rounded corner
54 .attr('role', "button").attr('id', 'expanbutton').attr('title', 'Grow the tooltip vertically (press tab 2 times)').click(function () {
54 .attr('role', "button").attr('id', 'expanbutton').attr('title', 'Grow the tooltip vertically (press tab 2 times)').click(function () {
55 that.expand()
55 that.expand();
56 }).append(
56 }).append(
57 $('<span/>').text('Expand').addClass('ui-icon').addClass('ui-icon-plus'));
57 $('<span/>').text('Expand').addClass('ui-icon').addClass('ui-icon-plus'));
58
58
@@ -121,9 +121,13 b' var IPython = (function (IPython) {'
121 this._old_cell = (cell) ? cell : null;
121 this._old_cell = (cell) ? cell : null;
122 this._old_request = (text) ? text : null;
122 this._old_request = (text) ? text : null;
123 this._consecutive_counter = 0;
123 this._consecutive_counter = 0;
124 }
124 };
125 };
125 };
126
126
127 Tooltip.prototype.is_visible = function () {
128 return !this._hidden;
129 };
130
127 Tooltip.prototype.showInPager = function (cell) {
131 Tooltip.prototype.showInPager = function (cell) {
128 // reexecute last call in pager by appending ? to show back in pager
132 // reexecute last call in pager by appending ? to show back in pager
129 var that = this;
133 var that = this;
@@ -139,27 +143,27 b' var IPython = (function (IPython) {'
139 'store_history': true
143 'store_history': true
140 });
144 });
141 this.remove_and_cancel_tooltip();
145 this.remove_and_cancel_tooltip();
142 }
146 };
143
147
144 // grow the tooltip verticaly
148 // grow the tooltip verticaly
145 Tooltip.prototype.expand = function () {
149 Tooltip.prototype.expand = function () {
146 this.text.removeClass('smalltooltip');
150 this.text.removeClass('smalltooltip');
147 this.text.addClass('bigtooltip');
151 this.text.addClass('bigtooltip');
148 $('#expanbutton').hide('slow');
152 $('#expanbutton').hide('slow');
149 }
153 };
150
154
151 // deal with all the logic of hiding the tooltip
155 // deal with all the logic of hiding the tooltip
152 // and reset it's status
156 // and reset it's status
153 Tooltip.prototype._hide = function () {
157 Tooltip.prototype._hide = function () {
158 this._hidden = true;
154 this.tooltip.fadeOut('fast');
159 this.tooltip.fadeOut('fast');
155 $('#expanbutton').show('slow');
160 $('#expanbutton').show('slow');
156 this.text.removeClass('bigtooltip');
161 this.text.removeClass('bigtooltip');
157 this.text.addClass('smalltooltip');
162 this.text.addClass('smalltooltip');
158 // keep scroll top to be sure to always see the first line
163 // keep scroll top to be sure to always see the first line
159 this.text.scrollTop(0);
164 this.text.scrollTop(0);
160 this._hidden = true;
161 this.code_mirror = null;
165 this.code_mirror = null;
162 }
166 };
163
167
164 // return true on successfully removing a visible tooltip; otherwise return
168 // return true on successfully removing a visible tooltip; otherwise return
165 // false.
169 // false.
@@ -178,23 +182,23 b' var IPython = (function (IPython) {'
178 } else {
182 } else {
179 return false;
183 return false;
180 }
184 }
181 }
185 };
182
186
183 // cancel autocall done after '(' for example.
187 // cancel autocall done after '(' for example.
184 Tooltip.prototype.cancel_pending = function () {
188 Tooltip.prototype.cancel_pending = function () {
185 if (this._tooltip_timeout != null) {
189 if (this._tooltip_timeout !== null) {
186 clearTimeout(this._tooltip_timeout);
190 clearTimeout(this._tooltip_timeout);
187 this._tooltip_timeout = null;
191 this._tooltip_timeout = null;
188 }
192 }
189 }
193 };
190
194
191 // will trigger tooltip after timeout
195 // will trigger tooltip after timeout
192 Tooltip.prototype.pending = function (cell, hide_if_no_docstring) {
196 Tooltip.prototype.pending = function (cell, hide_if_no_docstring) {
193 var that = this;
197 var that = this;
194 this._tooltip_timeout = setTimeout(function () {
198 this._tooltip_timeout = setTimeout(function () {
195 that.request(cell, hide_if_no_docstring)
199 that.request(cell, hide_if_no_docstring);
196 }, that.time_before_tooltip);
200 }, that.time_before_tooltip);
197 }
201 };
198
202
199 // easy access for julia monkey patching.
203 // easy access for julia monkey patching.
200 Tooltip.last_token_re = /[a-z_][0-9a-z._]*$/gi;
204 Tooltip.last_token_re = /[a-z_][0-9a-z._]*$/gi;
@@ -219,7 +223,7 b' var IPython = (function (IPython) {'
219 line = line.replace(endBracket, "");
223 line = line.replace(endBracket, "");
220 // reset the regex object
224 // reset the regex object
221 Tooltip.last_token_re.lastIndex = 0;
225 Tooltip.last_token_re.lastIndex = 0;
222 return Tooltip.last_token_re.exec(line)
226 return Tooltip.last_token_re.exec(line);
223 };
227 };
224
228
225 Tooltip.prototype._request_tooltip = function (cell, line) {
229 Tooltip.prototype._request_tooltip = function (cell, line) {
@@ -252,7 +256,7 b' var IPython = (function (IPython) {'
252
256
253 // now we treat the different number of keypress
257 // now we treat the different number of keypress
254 // first if same cell, same text, increment counter by 1
258 // first if same cell, same text, increment counter by 1
255 if (this._old_cell == cell && this._old_request == text && this._hidden == false) {
259 if (this._old_cell == cell && this._old_request == text && this._hidden === false) {
256 this._consecutive_counter++;
260 this._consecutive_counter++;
257 } else {
261 } else {
258 // else reset
262 // else reset
@@ -273,7 +277,7 b' var IPython = (function (IPython) {'
273 }
277 }
274
278
275 return;
279 return;
276 }
280 };
277
281
278 // cancel the option of having the tooltip to stick
282 // cancel the option of having the tooltip to stick
279 Tooltip.prototype.cancel_stick = function () {
283 Tooltip.prototype.cancel_stick = function () {
@@ -281,14 +285,14 b' var IPython = (function (IPython) {'
281 this._stick_timeout = null;
285 this._stick_timeout = null;
282 this._clocklink.hide('slow');
286 this._clocklink.hide('slow');
283 this._sticky = false;
287 this._sticky = false;
284 }
288 };
285
289
286 // put the tooltip in a sicky state for 10 seconds
290 // put the tooltip in a sicky state for 10 seconds
287 // it won't be removed by remove_and_cancell() unless you called with
291 // it won't be removed by remove_and_cancell() unless you called with
288 // the first parameter set to true.
292 // the first parameter set to true.
289 // remove_and_cancell_tooltip(true)
293 // remove_and_cancell_tooltip(true)
290 Tooltip.prototype.stick = function (time) {
294 Tooltip.prototype.stick = function (time) {
291 time = (time != undefined) ? time : 10;
295 time = (time !== undefined) ? time : 10;
292 var that = this;
296 var that = this;
293 this._sticky = true;
297 this._sticky = true;
294 this._clocklink.show('slow');
298 this._clocklink.show('slow');
@@ -296,7 +300,7 b' var IPython = (function (IPython) {'
296 that._sticky = false;
300 that._sticky = false;
297 that._clocklink.hide('slow');
301 that._clocklink.hide('slow');
298 }, time * 1000);
302 }, time * 1000);
299 }
303 };
300
304
301 // should be called with the kernel reply to actually show the tooltip
305 // should be called with the kernel reply to actually show the tooltip
302 Tooltip.prototype._show = function (reply) {
306 Tooltip.prototype._show = function (reply) {
@@ -322,7 +326,7 b' var IPython = (function (IPython) {'
322 var xinter = o.left + (xinit - o.left) / w * (w - 450);
326 var xinter = o.left + (xinit - o.left) / w * (w - 450);
323 var posarrowleft = xinit - xinter;
327 var posarrowleft = xinit - xinter;
324
328
325 if (this._hidden == false) {
329 if (this._hidden === false) {
326 this.tooltip.animate({
330 this.tooltip.animate({
327 'left': xinter - 30 + 'px',
331 'left': xinter - 30 + 'px',
328 'top': (head.bottom + 10) + 'px'
332 'top': (head.bottom + 10) + 'px'
@@ -365,8 +369,8 b' var IPython = (function (IPython) {'
365 }
369 }
366 }
370 }
367
371
368 this.tooltip.fadeIn('fast');
369 this._hidden = false;
372 this._hidden = false;
373 this.tooltip.fadeIn('fast');
370 this.text.children().remove();
374 this.text.children().remove();
371
375
372 var pre = $('<pre/>').html(utils.fixConsole(docstring));
376 var pre = $('<pre/>').html(utils.fixConsole(docstring));
@@ -377,8 +381,7 b' var IPython = (function (IPython) {'
377 this.text.append(pre);
381 this.text.append(pre);
378 // keep scroll top to be sure to always see the first line
382 // keep scroll top to be sure to always see the first line
379 this.text.scrollTop(0);
383 this.text.scrollTop(0);
380 }
384 };
381
382
385
383 IPython.Tooltip = Tooltip;
386 IPython.Tooltip = Tooltip;
384
387
General Comments 0
You need to be logged in to leave comments. Login now