##// END OF EJS Templates
Post in person review...
Jonathan Frederic -
Show More
@@ -57,11 +57,6 b' var IPython = (function (IPython) {'
57 57 this.cell_type = this.cell_type || null;
58 58 this.code_mirror = null;
59 59
60 // This is a list of callbacks that are called when a cell's textual
61 // region is unfocused. If one of the callbacks returns True, the cell
62 // unfocus event will be ignored. Callbacks will be passed no arguments.
63 this.cancel_unfocus_callbacks = [];
64
65 60 this.create_element();
66 61 if (this.element !== null) {
67 62 this.element.data("cell", this);
@@ -80,8 +75,7 b' var IPython = (function (IPython) {'
80 75
81 76 // FIXME: Workaround CM Bug #332 (Safari segfault on drag)
82 77 // by disabling drag/drop altogether on Safari
83 // https://github.com/marijnh/CodeMirror/issues/332
84
78 // https://github.com/marijnh/CodeMirror/issues/332
85 79 if (utils.browser[0] == "Safari") {
86 80 Cell.options_default.cm_config.dragDrop = false;
87 81 }
@@ -89,11 +83,8 b' var IPython = (function (IPython) {'
89 83 Cell.prototype.mergeopt = function(_class, options, overwrite){
90 84 options = options || {};
91 85 overwrite = overwrite || {};
92 return $.extend(true, {}, _class.options_default, options, overwrite)
93
94 }
95
96
86 return $.extend(true, {}, _class.options_default, options, overwrite);
87 };
97 88
98 89 /**
99 90 * Empty. Subclasses must implement create_element.
@@ -272,10 +263,6 b' var IPython = (function (IPython) {'
272 263 * Check if this cell's unfocus event was legit.
273 264 */
274 265 Cell.prototype.should_cancel_unfocus = function () {
275 // Try user registered callbacks.
276 for (var i=0; i<this.cancel_unfocus_callbacks.length; i++) {
277 if (this.cancel_unfocus_callbacks[i]()) { return true; }
278 }
279 266 return false;
280 267 };
281 268
@@ -288,6 +275,17 b' var IPython = (function (IPython) {'
288 275 };
289 276
290 277 /**
278 * Focus the editor area so a user can type
279 *
280 * NOTE: If codemirror is focused via a mouse click event, you don't want to
281 * call this because it will cause a page jump.
282 * @method focus_editor
283 */
284 Cell.prototype.focus_editor = function () {
285 this.code_mirror.focus();
286 };
287
288 /**
291 289 * Refresh codemirror instance
292 290 * @method refresh
293 291 */
@@ -362,7 +360,7 b' var IPython = (function (IPython) {'
362 360 var text = this.code_mirror.getRange({line:0, ch:0}, cursor);
363 361 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
364 362 return text;
365 }
363 };
366 364
367 365
368 366 /**
@@ -373,7 +371,7 b' var IPython = (function (IPython) {'
373 371 var cursor = this.code_mirror.getCursor();
374 372 var last_line_num = this.code_mirror.lineCount()-1;
375 373 var last_line_len = this.code_mirror.getLine(last_line_num).length;
376 var end = {line:last_line_num, ch:last_line_len}
374 var end = {line:last_line_num, ch:last_line_len};
377 375 var text = this.code_mirror.getRange(cursor, end);
378 376 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
379 377 return text;
@@ -417,9 +415,10 b' var IPython = (function (IPython) {'
417 415 **/
418 416 Cell.prototype._auto_highlight = function (modes) {
419 417 //Here we handle manually selected modes
420 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
418 var mode;
419 if( this.user_highlight !== undefined && this.user_highlight != 'auto' )
421 420 {
422 var mode = this.user_highlight;
421 mode = this.user_highlight;
423 422 CodeMirror.autoLoadMode(this.code_mirror, mode);
424 423 this.code_mirror.setOption('mode', mode);
425 424 return;
@@ -427,22 +426,22 b' var IPython = (function (IPython) {'
427 426 var current_mode = this.code_mirror.getOption('mode', mode);
428 427 var first_line = this.code_mirror.getLine(0);
429 428 // loop on every pairs
430 for( var mode in modes) {
431 var regs = modes[mode]['reg'];
429 for(mode in modes) {
430 var regs = modes[mode].reg;
432 431 // only one key every time but regexp can't be keys...
433 432 for(var i=0; i<regs.length; i++) {
434 433 // here we handle non magic_modes
435 if(first_line.match(regs[i]) != null) {
434 if(first_line.match(regs[i]) !== null) {
436 435 if(current_mode == mode){
437 436 return;
438 437 }
439 if (mode.search('magic_') != 0) {
438 if (mode.search('magic_') !== 0) {
440 439 this.code_mirror.setOption('mode', mode);
441 440 CodeMirror.autoLoadMode(this.code_mirror, mode);
442 441 return;
443 442 }
444 var open = modes[mode]['open']|| "%%";
445 var close = modes[mode]['close']|| "%%end";
443 var open = modes[mode].open || "%%";
444 var close = modes[mode].close || "%%end";
446 445 var mmode = mode;
447 446 mode = mmode.substr(6);
448 447 if(current_mode == mode){
@@ -469,14 +468,14 b' var IPython = (function (IPython) {'
469 468 }
470 469 }
471 470 // fallback on default
472 var default_mode
471 var default_mode;
473 472 try {
474 473 default_mode = this._options.cm_config.mode;
475 474 } catch(e) {
476 475 default_mode = 'text/plain';
477 476 }
478 477 if( current_mode === default_mode){
479 return
478 return;
480 479 }
481 480 this.code_mirror.setOption('mode', default_mode);
482 481 };
@@ -410,9 +410,9 b' var IPython = (function (IPython) {'
410 410 return false;
411 411 };
412 412
413 CodeCell.prototype.edit_mode = function () {
413 CodeCell.prototype.edit_mode = function (focus_editor) {
414 414 var cont = IPython.Cell.prototype.edit_mode.apply(this);
415 if (this.mode === 'edit') {
415 if (cont && focus_editor) {
416 416 this.focus_editor();
417 417 }
418 418 return cont;
@@ -422,27 +422,10 b' var IPython = (function (IPython) {'
422 422 * Check if this cell's unfocus event was legit.
423 423 */
424 424 CodeCell.prototype.should_cancel_unfocus = function () {
425 // Call base
426 if (IPython.Cell.prototype.should_cancel_unfocus.apply(this)) { return true; }
427
428 // Cancel this unfocus event if the cell completer is open.
429 return (this.completer && this.completer.is_visible());
430 };
431
432 /**
433 * Focus the editor area so a user can type
434 * @method focus_editor
435 */
436 CodeCell.prototype.focus_editor = function () {
437 // Only focus the CM editor if it is not focused already. This prevents
438 // jumps related to the previous prompt position. Here we can't use
439 // IPython.utils.is_focused since it uses document.activeElement which
440 // may not be set by the time this is called. Instead look at the input
441 // element of codemirror directly to see if it is focused. Use the
442 // jQuery :focus pseudo selector (http://api.jquery.com/focus-selector/)
443 if (!$(this.code_mirror.win).is(':focus')) {
444 this.code_mirror.focus();
445 }
425 // Cancel this unfocus event if the base wants to cancel or the cell
426 // completer is open.
427 return IPython.Cell.prototype.should_cancel_unfocus.apply(this) ||
428 (this.completer && this.completer.is_visible());
446 429 };
447 430
448 431 CodeCell.prototype.select_all = function () {
@@ -676,9 +676,8 b' var IPython = (function (IPython) {'
676 676 };
677 677
678 678
679
680 679 // Main keyboard manager for the notebook
681
680
682 681 var KeyboardManager = function () {
683 682 this.mode = 'command';
684 683 this.enabled = true;
@@ -725,51 +724,49 b' var IPython = (function (IPython) {'
725 724 };
726 725
727 726 KeyboardManager.prototype.edit_mode = function () {
728 console.log('kb edit');
729 727 this.last_mode = this.mode;
730 728 this.mode = 'edit';
731 729 };
732 730
733 731 KeyboardManager.prototype.command_mode = function () {
734 console.log('kb command');
735 732 this.last_mode = this.mode;
736 733 this.mode = 'command';
737 734 };
738 735
739 736 KeyboardManager.prototype.enable = function () {
740 console.log('kb enable');
741 737 this.enabled = true;
742 738 };
743 739
744 740 KeyboardManager.prototype.disable = function () {
745 console.log('kb disable');
746 741 this.enabled = false;
747 742 };
748 743
749 744 KeyboardManager.prototype.register_events = function (e) {
750 745 var that = this;
751 746 var handle_focus = function () {
752 console.log('kb focus in');
753 747 that.disable();
754 748 };
755 749 var handle_blur = function () {
756 console.log('kb focus out');
757 750 that.enable();
758 751 };
759 752 e.on('focusin', handle_focus);
760 753 e.on('focusout', handle_blur);
761 754 // TODO: Very strange. The focusout event does not seem fire for the
762 // bootstrap text boxes on FF25&26...
763 e.find('*').blur(handle_blur);
764 e.on('DOMNodeInserted', function () {
765 e.find('*').blur(handle_blur);
755 // bootstrap textboxes on FF25&26...
756 e.find('input').blur(handle_blur);
757 e.on('DOMNodeInserted', function (event) {
758 var target = $(event.target);
759 if (target.is('input')) {
760 target.blur(handle_blur);
761 } else {
762 target.find('input').blur(handle_blur);
763 }
766 764 });
767 765 // There are times (raw_input) where we remove the element from the DOM before
768 766 // focusout is called. In this case we bind to the remove event of jQueryUI,
769 767 // which gets triggered upon removal, iff it is focused at the time.
770 768 e.on('remove', function () {
771 769 if (IPython.utils.is_focused(e[0])) {
772 console.log('kb remove');
773 770 that.enable();
774 771 }
775 772 });
@@ -55,12 +55,6 b' var IPython = (function (IPython) {'
55 55 this.notebook_name_blacklist_re = /[\/\\:]/;
56 56 this.nbformat = 3; // Increment this when changing the nbformat
57 57 this.nbformat_minor = 0; // Increment this when changing the nbformat
58
59 // This is a list of callbacks that are called when a cell's textual
60 // region is unfocused. If one of the callbacks returns True, the cell
61 // unfocus event will be ignored. Callbacks will be passed one argument,
62 // the cell instance.
63 this.cancel_unfocus_callbacks = [];
64 58 this.style();
65 59 this.create_elements();
66 60 this.bind_events();
@@ -122,11 +116,11 b' var IPython = (function (IPython) {'
122 116 });
123 117
124 118 $([IPython.events]).on('focus_text.Cell', function (event, data) {
125 that.handle_cell_text_focus(that.find_cell_index(data.cell));
119 that.handle_cell_text_focus(data.cell);
126 120 });
127 121
128 122 $([IPython.events]).on('blur_text.Cell', function (event, data) {
129 that.handle_cell_text_blur(that.find_cell_index(data.cell));
123 that.handle_cell_text_blur(data.cell);
130 124 });
131 125
132 126 $([IPython.events]).on('status_autorestarting.Kernel', function () {
@@ -522,7 +516,6 b' var IPython = (function (IPython) {'
522 516 };
523 517
524 518 Notebook.prototype.command_mode = function () {
525 console.log('notebook command_mode()');
526 519
527 520 // Make sure there isn't an edit mode cell lingering around.
528 521 var cell = this.get_cell(this.get_edit_index());
@@ -540,32 +533,23 b' var IPython = (function (IPython) {'
540 533 };
541 534
542 535 Notebook.prototype.edit_mode = function (index) {
543 console.log('notebook edit_mode()');
544 536
545 537 // Either use specified index or selected cell's index.
546 538 // Must explictly check for undefined CBool(0) = false.
539 var focus_editor = false;
547 540 if (index===undefined) {
548 541 index = this.get_selected_index();
542 focus_editor = true;
543 } else {
544 this.select(index);
549 545 }
550 var cell = this.get_cell(index);
551 546 // Make sure the cell exists.
547 var cell = this.get_cell(index);
552 548 if (cell === null) { return; }
553 549
554 // If another cell is currently in edit mode set it to command mode.
555 var edit_index = this.get_edit_index(index);
556 if (edit_index !== null) { // Must explictly check for null CBool(0) = false.
557 var edit_cell = this.get_cell(edit_index);
558 if (edit_cell) {
559 edit_cell.command_mode();
560 }
561 }
562
563 550 // Set the cell to edit mode and notify the keyboard manager if this
564 551 // is a change of mode for the notebook as a whole.
565 if (this.get_selected_index()!==index) {
566 this.select(index);
567 }
568 cell.edit_mode();
552 cell.edit_mode(focus_editor);
569 553 if (this.mode !== 'edit') {
570 554 this.mode = 'edit';
571 555 $([IPython.events]).trigger('edit_mode.Notebook');
@@ -579,30 +563,20 b' var IPython = (function (IPython) {'
579 563 cell.focus_cell();
580 564 };
581 565
582 Notebook.prototype.handle_cell_text_focus = function (index) {
583 this.edit_mode(index);
566 Notebook.prototype.handle_cell_text_focus = function (cell) {
567 console.log('notebook.handle_cell_text_focus', cell);
568 this.edit_mode(this.find_cell_index(cell));
584 569 };
585 570
586 Notebook.prototype.handle_cell_text_blur = function (index) {
587 var cell = this.get_cell(index);
588 if (!cell) {return;}
571 Notebook.prototype.handle_cell_text_blur = function (cell) {
572 // In Firefox the focus event is called before the blur event. In
573 // other words, two cells elements may be focused at any given time.
574 // This has been witnessed on Win7 x64 w/ FF 25&26.
575 console.log('notebook.handle_cell_text_blur', cell);
589 576
590 577 // Check if this unfocus event is legit.
591 578 if (!this.should_cancel_unfocus(cell)) {
592 // In Firefox the focus event is called before the blur event. In
593 // other words, two cells elements may be focused at any given time.
594 // This has been witnessed on Win7 x64 w/ FF 25. Here we only put the
595 // entire notebook in command mode iff the cell textbox being blured is
596 // the one that is currently in edit mode. Otherwise, we assume the
597 // event order has been reversed and we just put this particular cell
598 // in command mode.
599 if (index===this.get_edit_index(index)) {
600 console.log('full command_mode');
601 this.command_mode();
602 } else {
603 console.log('cell command_mode');
604 cell.command_mode();
605 }
579 this.command_mode();
606 580 }
607 581 };
608 582
@@ -612,18 +586,9 b' var IPython = (function (IPython) {'
612 586 // If the tooltip is visible, ignore the unfocus.
613 587 var tooltip_visible = IPython.tooltip && IPython.tooltip.is_visible();
614 588 if (tooltip_visible) { return true; }
615
616 // Try user registered callbacks.
617 for (var i=0; i<this.cancel_unfocus_callbacks.length; i++) {
618 if (this.cancel_unfocus_callbacks[i](cell)) { return true; }
619 }
620 589
621 590 // Check the cell's should_cancel_unfocus method.
622 if (cell.should_cancel_unfocus !== undefined && cell.should_cancel_unfocus()) {
623 return true;
624 } else {
625 return false;
626 }
591 return (cell.should_cancel_unfocus !== undefined && cell.should_cancel_unfocus());
627 592 };
628 593
629 594 // Cell movement
@@ -1482,7 +1447,6 b' var IPython = (function (IPython) {'
1482 1447 var cell = this.get_selected_cell();
1483 1448 var cell_index = this.find_cell_index(cell);
1484 1449
1485 console.log('execute cell command_mode');
1486 1450 cell.execute();
1487 1451 cell.focus_cell();
1488 1452 this.command_mode();
@@ -1503,16 +1467,14 b' var IPython = (function (IPython) {'
1503 1467 // If we are at the end always insert a new cell and return
1504 1468 if (cell_index === (this.ncells()-1)) {
1505 1469 this.insert_cell_below('code');
1506 this.select(cell_index+1);
1507 this.edit_mode();
1470 this.edit_mode(cell_index+1);
1508 1471 this.scroll_to_bottom();
1509 1472 this.set_dirty(true);
1510 1473 return;
1511 1474 }
1512 1475
1513 1476 this.insert_cell_below('code');
1514 this.select(cell_index+1);
1515 this.edit_mode();
1477 this.edit_mode(cell_index+1);
1516 1478 this.set_dirty(true);
1517 1479 };
1518 1480
@@ -1531,8 +1493,7 b' var IPython = (function (IPython) {'
1531 1493 // If we are at the end always insert a new cell and return
1532 1494 if (cell_index === (this.ncells()-1)) {
1533 1495 this.insert_cell_below('code');
1534 this.select(cell_index+1);
1535 this.edit_mode();
1496 this.edit_mode(cell_index+1);
1536 1497 this.scroll_to_bottom();
1537 1498 this.set_dirty(true);
1538 1499 return;
@@ -2008,8 +1969,7 b' var IPython = (function (IPython) {'
2008 1969 console.log('load notebook success');
2009 1970 if (this.ncells() === 0) {
2010 1971 this.insert_cell_below('code');
2011 this.select(0);
2012 this.edit_mode();
1972 this.edit_mode(0);
2013 1973 } else {
2014 1974 this.select(0);
2015 1975 this.command_mode();
@@ -2369,3 +2329,4 b' var IPython = (function (IPython) {'
2369 2329 return IPython;
2370 2330
2371 2331 }(IPython));
2332
@@ -81,7 +81,7 b' var IPython = (function (IPython) {'
81 81 this.celltoolbar = new IPython.CellToolbar(this);
82 82 inner_cell.append(this.celltoolbar.element);
83 83 var input_area = $('<div/>').addClass('text_cell_input border-box-sizing');
84 this.code_mirror = CodeMirror(input_area.get(0), this.cm_config);
84 this.code_mirror = new CodeMirror(input_area.get(0), this.cm_config);
85 85 // The tabindex=-1 makes this div focusable.
86 86 var render_area = $('<div/>').addClass('text_cell_render border-box-sizing').
87 87 addClass('rendered_html').attr('tabindex','-1');
@@ -104,7 +104,7 b' var IPython = (function (IPython) {'
104 104 this.element.dblclick(function () {
105 105 if (that.selected === false) {
106 106 $([IPython.events]).trigger('select.Cell', {'cell':that});
107 };
107 }
108 108 $([IPython.events]).trigger('edit_mode.Cell', {cell: that});
109 109 });
110 110 };
@@ -145,7 +145,7 b' var IPython = (function (IPython) {'
145 145 return false;
146 146 } else {
147 147 return true;
148 };
148 }
149 149 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
150 150 // If we are not at the bottom, let CM handle the down arrow and
151 151 // prevent the global keydown handler from handling it.
@@ -154,7 +154,7 b' var IPython = (function (IPython) {'
154 154 return false;
155 155 } else {
156 156 return true;
157 };
157 }
158 158 } else if (event.which === key.ESC && event.type === 'keydown') {
159 159 if (that.code_mirror.options.keyMap === "vim-insert") {
160 160 // vim keyMap is active and in insert mode. In this case we leave vim
@@ -179,7 +179,7 b' var IPython = (function (IPython) {'
179 179 if (this.mode === 'edit') {
180 180 this.code_mirror.refresh();
181 181 }
182 };
182 }
183 183 return cont;
184 184 };
185 185
@@ -196,7 +196,7 b' var IPython = (function (IPython) {'
196 196 this.refresh();
197 197 }
198 198
199 };
199 }
200 200 return cont;
201 201 };
202 202
@@ -204,14 +204,19 b' var IPython = (function (IPython) {'
204 204 this.render();
205 205 };
206 206
207 TextCell.prototype.edit_mode = function () {
207 TextCell.prototype.edit_mode = function (focus_editor) {
208 208 var cont = IPython.Cell.prototype.edit_mode.apply(this);
209 209 if (cont) {
210 this.unrender();
211 this.focus_editor();
212 };
210 cont = this.unrender();
211 // Focus the editor if codemirror was just added to the page or the
212 // caller explicitly wants to focus the editor (usally when the
213 // edit_mode was triggered by something other than a mouse click).
214 if (cont || focus_editor) {
215 this.focus_editor();
216 }
217 }
213 218 return cont;
214 }
219 };
215 220
216 221 /**
217 222 * setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
@@ -261,8 +266,8 b' var IPython = (function (IPython) {'
261 266 return true;
262 267 } else {
263 268 return false;
264 };
265 };
269 }
270 }
266 271 };
267 272
268 273 /**
@@ -278,8 +283,8 b' var IPython = (function (IPython) {'
278 283 return true;
279 284 } else {
280 285 return false;
281 };
282 };
286 }
287 }
283 288 };
284 289
285 290 /**
@@ -332,7 +337,7 b' var IPython = (function (IPython) {'
332 337 mode: 'gfm'
333 338 },
334 339 placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$"
335 }
340 };
336 341
337 342 MarkdownCell.prototype = new TextCell();
338 343
@@ -363,8 +368,8 b' var IPython = (function (IPython) {'
363 368 }
364 369 this.element.find('div.text_cell_input').hide();
365 370 this.element.find("div.text_cell_render").show();
366 this.typeset()
367 };
371 this.typeset();
372 }
368 373 return cont;
369 374 };
370 375
@@ -378,7 +383,7 b' var IPython = (function (IPython) {'
378 383 */
379 384 var RawCell = function (options) {
380 385
381 options = this.mergeopt(RawCell,options)
386 options = this.mergeopt(RawCell,options);
382 387 TextCell.apply(this, [options]);
383 388 this.cell_type = 'raw';
384 389 // RawCell should always hide its rendered div
@@ -396,7 +401,7 b' var IPython = (function (IPython) {'
396 401 /** @method bind_events **/
397 402 RawCell.prototype.bind_events = function () {
398 403 TextCell.prototype.bind_events.apply(this);
399 var that = this
404 var that = this;
400 405 this.element.focusout(function() {
401 406 that.auto_highlight();
402 407 });
@@ -452,7 +457,7 b' var IPython = (function (IPython) {'
452 457
453 458 /** @method fromJSON */
454 459 HeadingCell.prototype.fromJSON = function (data) {
455 if (data.level != undefined){
460 if (data.level !== undefined){
456 461 this.level = data.level;
457 462 }
458 463 TextCell.prototype.fromJSON.apply(this, arguments);
@@ -492,7 +497,7 b' var IPython = (function (IPython) {'
492 497 if (this.rendered) {
493 498 this.rendered = false;
494 499 this.render();
495 };
500 }
496 501 };
497 502
498 503 /** The depth of header cell, based on html (h1 to h6)
@@ -544,7 +549,7 b' var IPython = (function (IPython) {'
544 549 this.element.find('div.text_cell_input').hide();
545 550 this.element.find("div.text_cell_render").show();
546 551
547 };
552 }
548 553 return cont;
549 554 };
550 555
General Comments 0
You need to be logged in to leave comments. Login now