##// END OF EJS Templates
Major refactoring of the Notebook, Kernel and CodeCell JavaScript....
Brian Granger -
Show More
@@ -14,13 +14,9 b' var IPython = (function (IPython) {'
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16
16
17 var Cell = function (notebook) {
17 var Cell = function () {
18 this.placeholder = this.placeholder || '';
18 this.placeholder = this.placeholder || '';
19 this.notebook = notebook;
20 this.read_only = false;
19 this.read_only = false;
21 if (notebook){
22 this.read_only = notebook.read_only;
23 }
24 this.selected = false;
20 this.selected = false;
25 this.element = null;
21 this.element = null;
26 this.create_element();
22 this.create_element();
@@ -38,15 +34,15 b' var IPython = (function (IPython) {'
38
34
39 Cell.prototype.bind_events = function () {
35 Cell.prototype.bind_events = function () {
40 var that = this;
36 var that = this;
41 var nb = that.notebook;
37 // We trigger events so that Cell doesn't have to depend on Notebook.
42 that.element.click(function (event) {
38 that.element.click(function (event) {
43 if (that.selected === false) {
39 if (that.selected === false) {
44 nb.select(nb.find_cell_index(that));
40 $([IPython.events]).trigger('select.Cell', {'cell':that});
45 }
41 }
46 });
42 });
47 that.element.focusin(function (event) {
43 that.element.focusin(function (event) {
48 if (that.selected === false) {
44 if (that.selected === false) {
49 nb.select(nb.find_cell_index(that));
45 $([IPython.events]).trigger('select.Cell', {'cell':that});
50 }
46 }
51 });
47 });
52 };
48 };
@@ -15,12 +15,14 b' var IPython = (function (IPython) {'
15 var utils = IPython.utils;
15 var utils = IPython.utils;
16 var key = IPython.utils.keycodes;
16 var key = IPython.utils.keycodes;
17
17
18 var CodeCell = function (notebook) {
18 var CodeCell = function (kernel) {
19 this.kernel = kernel;
19 this.code_mirror = null;
20 this.code_mirror = null;
20 this.input_prompt_number = null;
21 this.input_prompt_number = null;
21 this.outputs = [];
22 this.outputs = [];
22 this.collapsed = false;
23 this.collapsed = false;
23 this.clear_out_timeout = null;
24 this.clear_out_timeout = null;
25 this.tooltip_on_tab = true;
24 IPython.Cell.apply(this, arguments);
26 IPython.Cell.apply(this, arguments);
25 };
27 };
26
28
@@ -65,7 +67,6 b' var IPython = (function (IPython) {'
65 return false;
67 return false;
66 }
68 }
67
69
68 var tooltip_on_tab = this.notebook.tooltip_on_tab;
69 var that = this;
70 var that = this;
70 // whatever key is pressed, first, cancel the tooltip request before
71 // whatever key is pressed, first, cancel the tooltip request before
71 // they are sent, and remove tooltip if any, except for tab again
72 // they are sent, and remove tooltip if any, except for tab again
@@ -73,11 +74,12 b' var IPython = (function (IPython) {'
73 IPython.tooltip.remove_and_cancel_tooltip();
74 IPython.tooltip.remove_and_cancel_tooltip();
74 };
75 };
75
76
77 var cur = editor.getCursor();
76
78
77 if (event.keyCode === key.enter && (event.shiftKey || event.ctrlKey)) {
79 if (event.keyCode === key.enter && (event.shiftKey || event.ctrlKey)) {
78 // Always ignore shift-enter in CodeMirror as we handle it.
80 // Always ignore shift-enter in CodeMirror as we handle it.
79 return true;
81 return true;
80 } else if (event.which === 40 && event.type === 'keypress' && this.notebook.time_before_tooltip >= 0) {
82 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
81 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
83 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
82 // browser and keyboard layout !
84 // browser and keyboard layout !
83 // Pressing '(' , request tooltip, don't forget to reappend it
85 // Pressing '(' , request tooltip, don't forget to reappend it
@@ -102,14 +104,13 b' var IPython = (function (IPython) {'
102 };
104 };
103 } else if (event.keyCode === key.tab && event.type == 'keydown') {
105 } else if (event.keyCode === key.tab && event.type == 'keydown') {
104 // Tab completion.
106 // Tab completion.
105 var cur = editor.getCursor();
106 //Do not trim here because of tooltip
107 //Do not trim here because of tooltip
107 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
108 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
108 if (pre_cursor.trim() === "") {
109 if (pre_cursor.trim() === "") {
109 // Don't autocomplete if the part of the line before the cursor
110 // Don't autocomplete if the part of the line before the cursor
110 // is empty. In this case, let CodeMirror handle indentation.
111 // is empty. In this case, let CodeMirror handle indentation.
111 return false;
112 return false;
112 } else if ((pre_cursor.substr(-1) === "("|| pre_cursor.substr(-1) === " ") && tooltip_on_tab ) {
113 } else if ((pre_cursor.substr(-1) === "("|| pre_cursor.substr(-1) === " ") && that.tooltip_on_tab ) {
113 IPython.tooltip.request(that);
114 IPython.tooltip.request(that);
114 // Prevent the event from bubbling up.
115 // Prevent the event from bubbling up.
115 event.stop();
116 event.stop();
@@ -122,7 +123,6 b' var IPython = (function (IPython) {'
122 };
123 };
123 } else if (event.keyCode === key.backspace && event.type == 'keydown') {
124 } else if (event.keyCode === key.backspace && event.type == 'keydown') {
124 // If backspace and the line ends with 4 spaces, remove them.
125 // If backspace and the line ends with 4 spaces, remove them.
125 var cur = editor.getCursor();
126 var line = editor.getLine(cur.line);
126 var line = editor.getLine(cur.line);
127 var ending = line.slice(-4);
127 var ending = line.slice(-4);
128 if (ending === ' ') {
128 if (ending === ' ') {
@@ -147,13 +147,56 b' var IPython = (function (IPython) {'
147 IPython.tooltip.show(reply, this);
147 IPython.tooltip.show(reply, this);
148 };
148 };
149
149
150 // Kernel related calls.
150
151
151 // called when completion came back from the kernel. just forward
152 CodeCell.prototype.execute = function () {
152 CodeCell.prototype.finish_completing = function (matched_text, matches) {
153 this.clear_output(true, true, true);
153 this.completer.finish_completing(matched_text,matches);
154 this.set_input_prompt('*');
155 this.element.addClass("running");
156 var code = this.get_text();
157 var callbacks = {
158 'execute_reply': $.proxy(this._handle_execute_reply, this),
159 'output': $.proxy(this._handle_output, this),
160 'clear_output': $.proxy(this._handle_clear_output, this),
161 'cell': this
162 };
163 var msg_id = this.kernel.execute(this.get_text(), callbacks);
164 };
165
166
167 CodeCell.prototype._handle_execute_reply = function (content) {
168 this.set_input_prompt(content.execution_count);
169 this.element.removeClass("running");
170 // this.dirty = true;
154 }
171 }
155
172
156
173
174 CodeCell.prototype.request_tooltip = function (func) {
175 // Feel free to shorten this logic if you are better
176 // than me in regEx
177 // basicaly you shoul be able to get xxx.xxx.xxx from
178 // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
179 // remove everything between matchin bracket (need to iterate)
180 var matchBracket = /\([^\(\)]+\)/g;
181 var endBracket = /\([^\(]*$/g;
182 var oldfunc = func;
183
184 func = func.replace(matchBracket,"");
185 while( oldfunc != func )
186 {
187 oldfunc = func;
188 func = func.replace(matchBracket,"");
189 }
190 // remove everythin after last open bracket
191 func = func.replace(endBracket,"");
192 var re = /[a-z_][0-9a-z._]+$/gi; // casse insensitive
193 var callbacks = {'object_info_reply': $.proxy(this.finish_tooltip,this)}
194 var msg_id = this.kernel.object_info_request(re.exec(func), callbacks);
195 };
196
197
198 // Basic cell manipulation.
199
157 CodeCell.prototype.select = function () {
200 CodeCell.prototype.select = function () {
158 IPython.Cell.prototype.select.apply(this);
201 IPython.Cell.prototype.select.apply(this);
159 this.code_mirror.refresh();
202 this.code_mirror.refresh();
@@ -173,6 +216,125 b' var IPython = (function (IPython) {'
173 };
216 };
174
217
175
218
219 CodeCell.prototype.collapse = function () {
220 if (!this.collapsed) {
221 this.element.find('div.output').hide();
222 this.collapsed = true;
223 };
224 };
225
226
227 CodeCell.prototype.expand = function () {
228 if (this.collapsed) {
229 this.element.find('div.output').show();
230 this.collapsed = false;
231 };
232 };
233
234
235 CodeCell.prototype.toggle_output = function () {
236 if (this.collapsed) {
237 this.expand();
238 } else {
239 this.collapse();
240 };
241 };
242
243
244 CodeCell.prototype.set_input_prompt = function (number) {
245 this.input_prompt_number = number;
246 var ns = number || " ";
247 this.element.find('div.input_prompt').html('In [' + ns + ']:');
248 };
249
250
251 CodeCell.prototype.clear_input = function () {
252 this.code_mirror.setValue('');
253 };
254
255
256 CodeCell.prototype.get_text = function () {
257 return this.code_mirror.getValue();
258 };
259
260
261 CodeCell.prototype.set_text = function (code) {
262 return this.code_mirror.setValue(code);
263 };
264
265
266 CodeCell.prototype.at_top = function () {
267 var cursor = this.code_mirror.getCursor();
268 if (cursor.line === 0) {
269 return true;
270 } else {
271 return false;
272 }
273 };
274
275
276 CodeCell.prototype.at_bottom = function () {
277 var cursor = this.code_mirror.getCursor();
278 if (cursor.line === (this.code_mirror.lineCount()-1)) {
279 return true;
280 } else {
281 return false;
282 }
283 };
284
285
286 // Output handling.
287
288 CodeCell.prototype._handle_output = function (msg_type, content) {
289 var json = {};
290 json.output_type = msg_type;
291 if (msg_type === "stream") {
292 json.text = content.data;
293 json.stream = content.name;
294 } else if (msg_type === "display_data") {
295 json = this.convert_mime_types(json, content.data);
296 } else if (msg_type === "pyout") {
297 json.prompt_number = content.execution_count;
298 json = this.convert_mime_types(json, content.data);
299 } else if (msg_type === "pyerr") {
300 json.ename = content.ename;
301 json.evalue = content.evalue;
302 json.traceback = content.traceback;
303 };
304 // append with dynamic=true
305 this.append_output(json, true);
306 };
307
308
309 CodeCell.prototype.convert_mime_types = function (json, data) {
310 if (data['text/plain'] !== undefined) {
311 json.text = data['text/plain'];
312 };
313 if (data['text/html'] !== undefined) {
314 json.html = data['text/html'];
315 };
316 if (data['image/svg+xml'] !== undefined) {
317 json.svg = data['image/svg+xml'];
318 };
319 if (data['image/png'] !== undefined) {
320 json.png = data['image/png'];
321 };
322 if (data['image/jpeg'] !== undefined) {
323 json.jpeg = data['image/jpeg'];
324 };
325 if (data['text/latex'] !== undefined) {
326 json.latex = data['text/latex'];
327 };
328 if (data['application/json'] !== undefined) {
329 json.json = data['application/json'];
330 };
331 if (data['application/javascript'] !== undefined) {
332 json.javascript = data['application/javascript'];
333 }
334 return json;
335 };
336
337
176 CodeCell.prototype.append_output = function (json, dynamic) {
338 CodeCell.prototype.append_output = function (json, dynamic) {
177 // If dynamic is true, javascript output will be eval'd.
339 // If dynamic is true, javascript output will be eval'd.
178 this.expand();
340 this.expand();
@@ -298,6 +460,7 b' var IPython = (function (IPython) {'
298 CodeCell.prototype.append_javascript = function (js, container) {
460 CodeCell.prototype.append_javascript = function (js, container) {
299 // We just eval the JS code, element appears in the local scope.
461 // We just eval the JS code, element appears in the local scope.
300 var element = $("<div/>").addClass("box_flex1 output_subarea");
462 var element = $("<div/>").addClass("box_flex1 output_subarea");
463 var kernel = this.kernel;
301 container.append(element);
464 container.append(element);
302 // Div for js shouldn't be drawn, as it will add empty height to the area.
465 // Div for js shouldn't be drawn, as it will add empty height to the area.
303 container.hide();
466 container.hide();
@@ -349,6 +512,11 b' var IPython = (function (IPython) {'
349 };
512 };
350
513
351
514
515 CodeCell.prototype._handle_clear_output = function (content) {
516 this.clear_output(content.stdout, content.stderr, content.other);
517 }
518
519
352 CodeCell.prototype.clear_output = function (stdout, stderr, other) {
520 CodeCell.prototype.clear_output = function (stdout, stderr, other) {
353 var that = this;
521 var that = this;
354 if (this.clear_out_timeout != null){
522 if (this.clear_out_timeout != null){
@@ -361,7 +529,7 b' var IPython = (function (IPython) {'
361 this._clear_stdout = stdout;
529 this._clear_stdout = stdout;
362 this._clear_stderr = stderr;
530 this._clear_stderr = stderr;
363 this._clear_other = other;
531 this._clear_other = other;
364 this.clear_out_timeout = setTimeout(function(){
532 this.clear_out_timeout = setTimeout(function() {
365 // really clear timeout only after a short delay
533 // really clear timeout only after a short delay
366 // this reduces flicker in 'clear_output; print' cases
534 // this reduces flicker in 'clear_output; print' cases
367 that.clear_out_timeout = null;
535 that.clear_out_timeout = null;
@@ -370,7 +538,8 b' var IPython = (function (IPython) {'
370 }, 500
538 }, 500
371 );
539 );
372 };
540 };
373
541
542
374 CodeCell.prototype.clear_output_callback = function (stdout, stderr, other) {
543 CodeCell.prototype.clear_output_callback = function (stdout, stderr, other) {
375 var output_div = this.element.find("div.output");
544 var output_div = this.element.find("div.output");
376
545
@@ -383,26 +552,26 b' var IPython = (function (IPython) {'
383 // remove html output
552 // remove html output
384 // each output_subarea that has an identifying class is in an output_area
553 // each output_subarea that has an identifying class is in an output_area
385 // which is the element to be removed.
554 // which is the element to be removed.
386 if (stdout){
555 if (stdout) {
387 output_div.find("div.output_stdout").parent().remove();
556 output_div.find("div.output_stdout").parent().remove();
388 }
557 }
389 if (stderr){
558 if (stderr) {
390 output_div.find("div.output_stderr").parent().remove();
559 output_div.find("div.output_stderr").parent().remove();
391 }
560 }
392 if (other){
561 if (other) {
393 output_div.find("div.output_subarea").not("div.output_stderr").not("div.output_stdout").parent().remove();
562 output_div.find("div.output_subarea").not("div.output_stderr").not("div.output_stdout").parent().remove();
394 }
563 }
395
564
396 // remove cleared outputs from JSON list:
565 // remove cleared outputs from JSON list:
397 for (var i = this.outputs.length - 1; i >= 0; i--){
566 for (var i = this.outputs.length - 1; i >= 0; i--) {
398 var out = this.outputs[i];
567 var out = this.outputs[i];
399 var output_type = out.output_type;
568 var output_type = out.output_type;
400 if (output_type == "display_data" && other){
569 if (output_type == "display_data" && other) {
401 this.outputs.splice(i,1);
570 this.outputs.splice(i,1);
402 }else if (output_type == "stream"){
571 } else if (output_type == "stream") {
403 if (stdout && out.stream == "stdout"){
572 if (stdout && out.stream == "stdout") {
404 this.outputs.splice(i,1);
573 this.outputs.splice(i,1);
405 }else if (stderr && out.stream == "stderr"){
574 } else if (stderr && out.stream == "stderr") {
406 this.outputs.splice(i,1);
575 this.outputs.splice(i,1);
407 }
576 }
408 }
577 }
@@ -410,10 +579,6 b' var IPython = (function (IPython) {'
410 };
579 };
411
580
412
581
413 CodeCell.prototype.clear_input = function () {
414 this.code_mirror.setValue('');
415 };
416
417 CodeCell.prototype.flush_clear_timeout = function() {
582 CodeCell.prototype.flush_clear_timeout = function() {
418 var output_div = this.element.find('div.output');
583 var output_div = this.element.find('div.output');
419 if (this.clear_out_timeout){
584 if (this.clear_out_timeout){
@@ -424,66 +589,7 b' var IPython = (function (IPython) {'
424 }
589 }
425
590
426
591
427 CodeCell.prototype.collapse = function () {
592 // JSON serialization
428 if (!this.collapsed) {
429 this.element.find('div.output').hide();
430 this.collapsed = true;
431 };
432 };
433
434
435 CodeCell.prototype.expand = function () {
436 if (this.collapsed) {
437 this.element.find('div.output').show();
438 this.collapsed = false;
439 };
440 };
441
442
443 CodeCell.prototype.toggle_output = function () {
444 if (this.collapsed) {
445 this.expand();
446 } else {
447 this.collapse();
448 };
449 };
450
451 CodeCell.prototype.set_input_prompt = function (number) {
452 this.input_prompt_number = number;
453 var ns = number || "&nbsp;";
454 this.element.find('div.input_prompt').html('In&nbsp;[' + ns + ']:');
455 };
456
457
458 CodeCell.prototype.get_text = function () {
459 return this.code_mirror.getValue();
460 };
461
462
463 CodeCell.prototype.set_text = function (code) {
464 return this.code_mirror.setValue(code);
465 };
466
467
468 CodeCell.prototype.at_top = function () {
469 var cursor = this.code_mirror.getCursor();
470 if (cursor.line === 0) {
471 return true;
472 } else {
473 return false;
474 }
475 };
476
477
478 CodeCell.prototype.at_bottom = function () {
479 var cursor = this.code_mirror.getCursor();
480 if (cursor.line === (this.code_mirror.lineCount()-1)) {
481 return true;
482 } else {
483 return false;
484 }
485 };
486
487
593
488 CodeCell.prototype.fromJSON = function (data) {
594 CodeCell.prototype.fromJSON = function (data) {
489 if (data.cell_type === 'code') {
595 if (data.cell_type === 'code') {
@@ -37,7 +37,6 b' var IPython = (function(IPython ) {'
37
37
38
38
39 var Completer = function(cell) {
39 var Completer = function(cell) {
40 this.cell = cell;
41 this.editor = cell.code_mirror;
40 this.editor = cell.code_mirror;
42 // if last caractere before cursor is not in this, we stop completing
41 // if last caractere before cursor is not in this, we stop completing
43 this.reg = /[0-9a-z.]/i; // casse insensitive
42 this.reg = /[0-9a-z.]/i; // casse insensitive
@@ -47,7 +46,8 b' var IPython = (function(IPython ) {'
47 var cur = this.editor.getCursor();
46 var cur = this.editor.getCursor();
48 var line = this.editor.getLine(cur.line);
47 var line = this.editor.getLine(cur.line);
49 // one could fork here and directly call finish completing if kernel is busy
48 // one could fork here and directly call finish completing if kernel is busy
50 IPython.notebook.complete_cell(this.cell, line, cur.ch);
49 var callbacks = {'complete_reply': $.proxy(this.finish_completing,this)};
50 IPython.notebook.kernel.complete(line, cur.ch, callbacks);
51 }
51 }
52
52
53
53
@@ -85,9 +85,11 b' var IPython = (function(IPython ) {'
85 this.kernelCompletionRequest();
85 this.kernelCompletionRequest();
86 }
86 }
87
87
88 Completer.prototype.finish_completing =function (matched_text, matches) {
88 Completer.prototype.finish_completing =function (content) {
89 // let's build a function that wrap all that stuff into what is needed
89 // let's build a function that wrap all that stuff into what is needed
90 // for the new completer:
90 // for the new completer:
91 var matched_text = content.matched_text;
92 var matches = content.matches;
91
93
92 var cur = this.editor.getCursor();
94 var cur = this.editor.getCursor();
93 var results = CodeMirror.contextHint(this.editor);
95 var results = CodeMirror.contextHint(this.editor);
@@ -12,7 +12,7 b''
12 // Give us an object to bind all events to. This object should be created
12 // Give us an object to bind all events to. This object should be created
13 // before all other objects so it exists when others register event handlers.
13 // before all other objects so it exists when others register event handlers.
14 // To trigger an event handler:
14 // To trigger an event handler:
15 // $([IPython.events]).trigger('event.Namespace);
15 // $([IPython.events]).trigger('event.Namespace');
16 // To handle it:
16 // To handle it:
17 // $([IPython.events]).on('event.Namespace',function () {});
17 // $([IPython.events]).on('event.Namespace',function () {});
18
18
@@ -13,15 +13,18 b' var IPython = (function (IPython) {'
13
13
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16 var Kernel = function () {
16 // Initialization and connection.
17
18 var Kernel = function (base_url) {
17 this.kernel_id = null;
19 this.kernel_id = null;
18 this.shell_channel = null;
20 this.shell_channel = null;
19 this.iopub_channel = null;
21 this.iopub_channel = null;
20 this.base_url = $('body').data('baseKernelUrl') + "kernels";
22 this.base_url = base_url;
21 this.running = false;
23 this.running = false;
22 this.username = "username";
24 this.username = "username";
23 this.session_id = utils.uuid();
25 this.session_id = utils.uuid();
24
26 this._msg_callbacks = {};
27
25 if (typeof(WebSocket) !== 'undefined') {
28 if (typeof(WebSocket) !== 'undefined') {
26 this.WebSocket = WebSocket;
29 this.WebSocket = WebSocket;
27 } else if (typeof(MozWebSocket) !== 'undefined') {
30 } else if (typeof(MozWebSocket) !== 'undefined') {
@@ -32,7 +35,7 b' var IPython = (function (IPython) {'
32 };
35 };
33
36
34
37
35 Kernel.prototype.get_msg = function (msg_type, content) {
38 Kernel.prototype._get_msg = function (msg_type, content) {
36 var msg = {
39 var msg = {
37 header : {
40 header : {
38 msg_id : utils.uuid(),
41 msg_id : utils.uuid(),
@@ -46,46 +49,45 b' var IPython = (function (IPython) {'
46 return msg;
49 return msg;
47 };
50 };
48
51
49 Kernel.prototype.start = function (notebook_id, callback) {
52 Kernel.prototype.start = function (notebook_id) {
50 var that = this;
53 var that = this;
51 if (!this.running) {
54 if (!this.running) {
52 var qs = $.param({notebook:notebook_id});
55 var qs = $.param({notebook:notebook_id});
53 var url = this.base_url + '?' + qs;
56 var url = this.base_url + '?' + qs;
54 $.post(url,
57 $.post(url,
55 function (kernel_id) {
58 $.proxy(that._kernel_started,that),
56 that._handle_start_kernel(kernel_id, callback);
57 },
58 'json'
59 'json'
59 );
60 );
60 };
61 };
61 };
62 };
62
63
63
64
64 Kernel.prototype.restart = function (callback) {
65 Kernel.prototype.restart = function () {
65 $([IPython.events]).trigger('status_restarting.Kernel');
66 $([IPython.events]).trigger('status_restarting.Kernel');
66 var url = this.kernel_url + "/restart";
67 var that = this;
67 var that = this;
68 if (this.running) {
68 if (this.running) {
69 this.stop_channels();
69 this.stop_channels();
70 var url = this.kernel_url + "/restart";
70 $.post(url,
71 $.post(url,
71 function (kernel_id) {
72 $.proxy(that._kernel_started, that),
72 that._handle_start_kernel(kernel_id, callback);
73 },
74 'json'
73 'json'
75 );
74 );
76 };
75 };
77 };
76 };
78
77
79
78
80 Kernel.prototype._handle_start_kernel = function (json, callback) {
79 Kernel.prototype._kernel_started = function (json) {
80 console.log("Kernel started: ", json.kernel_id);
81 this.running = true;
81 this.running = true;
82 this.kernel_id = json.kernel_id;
82 this.kernel_id = json.kernel_id;
83 this.ws_url = json.ws_url;
83 this.ws_url = json.ws_url;
84 this.kernel_url = this.base_url + "/" + this.kernel_id;
84 this.kernel_url = this.base_url + "/" + this.kernel_id;
85 this.start_channels();
85 this.start_channels();
86 callback();
86 this.shell_channel.onmessage = $.proxy(this._handle_shell_reply,this);
87 this.iopub_channel.onmessage = $.proxy(this._handle_iopub_reply,this);
87 };
88 };
88
89
90
89 Kernel.prototype._websocket_closed = function(ws_url, early){
91 Kernel.prototype._websocket_closed = function(ws_url, early){
90 var msg;
92 var msg;
91 var parent_item = $('body');
93 var parent_item = $('body');
@@ -114,7 +116,7 b' var IPython = (function (IPython) {'
114 }
116 }
115 }
117 }
116 });
118 });
117
119
118 };
120 };
119
121
120 Kernel.prototype.start_channels = function () {
122 Kernel.prototype.start_channels = function () {
@@ -171,20 +173,58 b' var IPython = (function (IPython) {'
171 };
173 };
172 };
174 };
173
175
174 Kernel.prototype.object_info_request = function (objname) {
176 // Main public methods.
177
178 Kernel.prototype.object_info_request = function (objname, callbacks) {
179 // When calling this method pass a callbacks structure of the form:
180 //
181 // callbacks = {
182 // 'object_info_reply': object_into_reply_callback
183 // }
184 //
185 // The object_info_reply_callback will be passed the content object of the
186 // object_into_reply message documented here:
187 //
188 // http://ipython.org/ipython-doc/dev/development/messaging.html#object-information
175 if(typeof(objname)!=null && objname!=null)
189 if(typeof(objname)!=null && objname!=null)
176 {
190 {
177 var content = {
191 var content = {
178 oname : objname.toString(),
192 oname : objname.toString(),
179 };
193 };
180 var msg = this.get_msg("object_info_request", content);
194 var msg = this._get_msg("object_info_request", content);
181 this.shell_channel.send(JSON.stringify(msg));
195 this.shell_channel.send(JSON.stringify(msg));
196 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
182 return msg.header.msg_id;
197 return msg.header.msg_id;
183 }
198 }
184 return;
199 return;
185 }
200 }
186
201
187 Kernel.prototype.execute = function (code) {
202 Kernel.prototype.execute = function (code, callbacks) {
203 // When calling this method pass a callbacks structure of the form:
204 //
205 // callbacks = {
206 // 'execute_reply': execute_reply_callback,
207 // 'output': output_callback,
208 // 'clear_output': clear_output_callback,
209 // 'cell': cell
210 // }
211 //
212 // The execute_reply_callback will be passed the content object of the execute_reply
213 // message documented here:
214 //
215 // http://ipython.org/ipython-doc/dev/development/messaging.html#execute
216 //
217 // The output_callback will be passed msg_type ('stream','display_data','pyout','pyerr')
218 // of the output and the content object of the PUB/SUB channel that contains the
219 // output:
220 //
221 // http://ipython.org/ipython-doc/dev/development/messaging.html#messages-on-the-pub-sub-socket
222 //
223 // The clear_output_callback will be passed a content object that contains
224 // stdout, stderr and other fields that are booleans.
225 //
226 // The cell value will contain the a cell object that the notebook can use for the
227 // set_next_input payload.
188 var content = {
228 var content = {
189 code : code,
229 code : code,
190 silent : false,
230 silent : false,
@@ -192,20 +232,32 b' var IPython = (function (IPython) {'
192 user_expressions : {},
232 user_expressions : {},
193 allow_stdin : false
233 allow_stdin : false
194 };
234 };
195 var msg = this.get_msg("execute_request", content);
235 var msg = this._get_msg("execute_request", content);
196 this.shell_channel.send(JSON.stringify(msg));
236 this.shell_channel.send(JSON.stringify(msg));
237 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
197 return msg.header.msg_id;
238 return msg.header.msg_id;
198 };
239 };
199
240
200
241
201 Kernel.prototype.complete = function (line, cursor_pos) {
242 Kernel.prototype.complete = function (line, cursor_pos, callbacks) {
243 // When calling this method pass a callbacks structure of the form:
244 //
245 // callbacks = {
246 // 'complete_reply': complete_reply_callback
247 // }
248 //
249 // The complete_reply_callback will be passed the content object of the
250 // complete_reply message documented here:
251 //
252 // http://ipython.org/ipython-doc/dev/development/messaging.html#complete
202 var content = {
253 var content = {
203 text : '',
254 text : '',
204 line : line,
255 line : line,
205 cursor_pos : cursor_pos
256 cursor_pos : cursor_pos
206 };
257 };
207 var msg = this.get_msg("complete_request", content);
258 var msg = this._get_msg("complete_request", content);
208 this.shell_channel.send(JSON.stringify(msg));
259 this.shell_channel.send(JSON.stringify(msg));
260 this.set_callbacks_for_msg(msg.header.msg_id, callbacks);
209 return msg.header.msg_id;
261 return msg.header.msg_id;
210 };
262 };
211
263
@@ -229,6 +281,90 b' var IPython = (function (IPython) {'
229 };
281 };
230 };
282 };
231
283
284
285 // Reply handlers.
286
287 Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
288 var callbacks = this._msg_callbacks[msg_id];
289 return callbacks;
290 };
291
292
293 Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
294 this._msg_callbacks[msg_id] = callbacks;
295 }
296
297
298 Kernel.prototype._handle_shell_reply = function (e) {
299 reply = $.parseJSON(e.data);
300 var header = reply.header;
301 var content = reply.content;
302 var msg_type = header.msg_type;
303 var callbacks = this.get_callbacks_for_msg(reply.parent_header.msg_id);
304 if (callbacks !== undefined) {
305 var cb = callbacks[msg_type];
306 if (cb !== undefined) {
307 cb(content);
308 }
309 };
310
311 if (content.payload !== undefined) {
312 var payload = content.payload || [];
313 this._handle_payload(callbacks.cell, payload);
314 }
315 };
316
317
318 Kernel.prototype._handle_payload = function (cell, payload) {
319 var l = payload.length;
320 // Payloads are handled by triggering events because we don't want the Kernel
321 // to depend on the Notebook or Pager classes.
322 for (var i=0; i<l; i++) {
323 if (payload[i].source === 'IPython.zmq.page.page') {
324 var data = {'text':payload[i].text}
325 $([IPython.events]).trigger('open_with_text.Pager', data);
326 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input' && cell !== undefined) {
327 var data = {'cell': cell, 'text': payload[i].text}
328 $([IPython.events]).trigger('set_next_input.Notebook', data);
329 }
330 };
331 };
332
333
334 Kernel.prototype._handle_iopub_reply = function (e) {
335 reply = $.parseJSON(e.data);
336 var content = reply.content;
337 var msg_type = reply.header.msg_type;
338 var callbacks = this.get_callbacks_for_msg(reply.parent_header.msg_id);
339 if (msg_type !== 'status' && callbacks === undefined) {
340 // Message not from one of this notebook's cells and there are no
341 // callbacks to handle it.
342 return;
343 }
344 var output_types = ['stream','display_data','pyout','pyerr'];
345 if (output_types.indexOf(msg_type) >= 0) {
346 var cb = callbacks['output'];
347 if (cb !== undefined) {
348 cb(msg_type, content);
349 }
350 } else if (msg_type === 'status') {
351 if (content.execution_state === 'busy') {
352 $([IPython.events]).trigger('status_busy.Kernel');
353 } else if (content.execution_state === 'idle') {
354 $([IPython.events]).trigger('status_idle.Kernel');
355 } else if (content.execution_state === 'dead') {
356 this.stop_channels();
357 $([IPython.events]).trigger('status_dead.Kernel');
358 };
359 } else if (msg_type === 'clear_output') {
360 var cb = callbacks['clear_output'];
361 if (cb !== undefined) {
362 cb(content);
363 }
364 };
365 };
366
367
232 IPython.Kernel = Kernel;
368 IPython.Kernel = Kernel;
233
369
234 return IPython;
370 return IPython;
@@ -24,7 +24,6 b' var IPython = (function (IPython) {'
24 this.clipboard = null;
24 this.clipboard = null;
25 this.paste_enabled = false;
25 this.paste_enabled = false;
26 this.dirty = false;
26 this.dirty = false;
27 this.msg_cell_map = {};
28 this.metadata = {};
27 this.metadata = {};
29 this.control_key_active = false;
28 this.control_key_active = false;
30 this.notebook_id = null;
29 this.notebook_id = null;
@@ -34,9 +33,6 b' var IPython = (function (IPython) {'
34 this.style();
33 this.style();
35 this.create_elements();
34 this.create_elements();
36 this.bind_events();
35 this.bind_events();
37 this.set_tooltipontab(true);
38 this.set_smartcompleter(true);
39 this.set_timebeforetooltip(1200);
40 };
36 };
41
37
42
38
@@ -64,6 +60,20 b' var IPython = (function (IPython) {'
64
60
65 Notebook.prototype.bind_events = function () {
61 Notebook.prototype.bind_events = function () {
66 var that = this;
62 var that = this;
63
64 $([IPython.events]).on('set_next_input.Notebook', function (event, data) {
65 var index = that.find_cell_index(data.cell);
66 var new_cell = that.insert_cell_below('code',index);
67 new_cell.set_text(data.text);
68 that.dirty = true;
69 });
70
71 $([IPython.events]).on('select.Cell', function (event, data) {
72 var index = that.find_cell_index(data.cell);
73 that.select(index);
74 });
75
76
67 $(document).keydown(function (event) {
77 $(document).keydown(function (event) {
68 // console.log(event);
78 // console.log(event);
69 if (that.read_only) return true;
79 if (that.read_only) return true;
@@ -393,19 +403,6 b' var IPython = (function (IPython) {'
393 };
403 };
394
404
395
405
396 Notebook.prototype.cell_for_msg = function (msg_id) {
397 var cell_id = this.msg_cell_map[msg_id];
398 var result = null;
399 this.get_cell_elements().filter(function (index) {
400 cell = $(this).data("cell");
401 if (cell.cell_id === cell_id) {
402 result = cell;
403 };
404 });
405 return result;
406 };
407
408
409 // Cell selection.
406 // Cell selection.
410
407
411 Notebook.prototype.select = function (index) {
408 Notebook.prototype.select = function (index) {
@@ -528,16 +525,16 b' var IPython = (function (IPython) {'
528 var cell = null;
525 var cell = null;
529 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
526 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
530 if (type === 'code') {
527 if (type === 'code') {
531 cell = new IPython.CodeCell(this);
528 cell = new IPython.CodeCell(this.kernel);
532 cell.set_input_prompt();
529 cell.set_input_prompt();
533 } else if (type === 'markdown') {
530 } else if (type === 'markdown') {
534 cell = new IPython.MarkdownCell(this);
531 cell = new IPython.MarkdownCell();
535 } else if (type === 'html') {
532 } else if (type === 'html') {
536 cell = new IPython.HTMLCell(this);
533 cell = new IPython.HTMLCell();
537 } else if (type === 'raw') {
534 } else if (type === 'raw') {
538 cell = new IPython.RawCell(this);
535 cell = new IPython.RawCell();
539 } else if (type === 'heading') {
536 } else if (type === 'heading') {
540 cell = new IPython.HeadingCell(this);
537 cell = new IPython.HeadingCell();
541 };
538 };
542 if (cell !== null) {
539 if (cell !== null) {
543 if (this.ncells() === 0) {
540 if (this.ncells() === 0) {
@@ -562,16 +559,16 b' var IPython = (function (IPython) {'
562 var cell = null;
559 var cell = null;
563 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
560 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
564 if (type === 'code') {
561 if (type === 'code') {
565 cell = new IPython.CodeCell(this);
562 cell = new IPython.CodeCell(this.kernel);
566 cell.set_input_prompt();
563 cell.set_input_prompt();
567 } else if (type === 'markdown') {
564 } else if (type === 'markdown') {
568 cell = new IPython.MarkdownCell(this);
565 cell = new IPython.MarkdownCell();
569 } else if (type === 'html') {
566 } else if (type === 'html') {
570 cell = new IPython.HTMLCell(this);
567 cell = new IPython.HTMLCell();
571 } else if (type === 'raw') {
568 } else if (type === 'raw') {
572 cell = new IPython.RawCell(this);
569 cell = new IPython.RawCell();
573 } else if (type === 'heading') {
570 } else if (type === 'heading') {
574 cell = new IPython.HeadingCell(this);
571 cell = new IPython.HeadingCell();
575 };
572 };
576 if (cell !== null) {
573 if (cell !== null) {
577 if (this.ncells() === 0) {
574 if (this.ncells() === 0) {
@@ -864,21 +861,6 b' var IPython = (function (IPython) {'
864 };
861 };
865
862
866
863
867 Notebook.prototype.set_timebeforetooltip = function (time) {
868 this.time_before_tooltip = time;
869 };
870
871
872 Notebook.prototype.set_tooltipontab = function (state) {
873 this.tooltip_on_tab = state;
874 };
875
876
877 Notebook.prototype.set_smartcompleter = function (state) {
878 this.smart_completer = state;
879 };
880
881
882 Notebook.prototype.clear_all_output = function () {
864 Notebook.prototype.clear_all_output = function () {
883 var ncells = this.ncells();
865 var ncells = this.ncells();
884 var cells = this.get_cells();
866 var cells = this.get_cells();
@@ -903,8 +885,9 b' var IPython = (function (IPython) {'
903 // Kernel related things
885 // Kernel related things
904
886
905 Notebook.prototype.start_kernel = function () {
887 Notebook.prototype.start_kernel = function () {
906 this.kernel = new IPython.Kernel();
888 var base_url = $('body').data('baseKernelUrl') + "kernels";
907 this.kernel.start(this.notebook_id, $.proxy(this.kernel_started, this));
889 this.kernel = new IPython.Kernel(base_url);
890 this.kernel.start(this.notebook_id);
908 };
891 };
909
892
910
893
@@ -920,117 +903,7 b' var IPython = (function (IPython) {'
920 closeText: '',
903 closeText: '',
921 buttons : {
904 buttons : {
922 "Restart": function () {
905 "Restart": function () {
923 that.kernel.restart($.proxy(that.kernel_started, that));
906 that.kernel.restart();
924 $(this).dialog('close');
925 },
926 "Continue running": function () {
927 $(this).dialog('close');
928 }
929 }
930 });
931 };
932
933
934 Notebook.prototype.kernel_started = function () {
935 console.log("Kernel started: ", this.kernel.kernel_id);
936 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
937 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
938 };
939
940
941 Notebook.prototype.handle_shell_reply = function (e) {
942 reply = $.parseJSON(e.data);
943 var header = reply.header;
944 var content = reply.content;
945 var msg_type = header.msg_type;
946 // console.log(reply);
947 var cell = this.cell_for_msg(reply.parent_header.msg_id);
948 if (msg_type === "execute_reply") {
949 cell.set_input_prompt(content.execution_count);
950 cell.element.removeClass("running");
951 this.dirty = true;
952 } else if (msg_type === "complete_reply") {
953 cell.finish_completing(content.matched_text, content.matches);
954 } else if (msg_type === "object_info_reply"){
955 //console.log('back from object_info_request : ')
956 rep = reply.content;
957 if(rep.found)
958 {
959 cell.finish_tooltip(rep);
960 }
961 } else {
962 //console.log("unknown reply:"+msg_type);
963 }
964 // when having a rely from object_info_reply,
965 // no payload so no nned to handle it
966 if(typeof(content.payload)!='undefined') {
967 var payload = content.payload || [];
968 this.handle_payload(cell, payload);
969 }
970 };
971
972
973 Notebook.prototype.handle_payload = function (cell, payload) {
974 var l = payload.length;
975 for (var i=0; i<l; i++) {
976 if (payload[i].source === 'IPython.zmq.page.page') {
977 if (payload[i].text.trim() !== '') {
978 IPython.pager.clear();
979 IPython.pager.expand();
980 IPython.pager.append_text(payload[i].text);
981 }
982 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
983 var index = this.find_cell_index(cell);
984 var new_cell = this.insert_cell_below('code',index);
985 new_cell.set_text(payload[i].text);
986 this.dirty = true;
987 }
988 };
989 };
990
991
992 Notebook.prototype.handle_iopub_reply = function (e) {
993 reply = $.parseJSON(e.data);
994 var content = reply.content;
995 // console.log(reply);
996 var msg_type = reply.header.msg_type;
997 var cell = this.cell_for_msg(reply.parent_header.msg_id);
998 if (msg_type !== 'status' && !cell){
999 // message not from this notebook, but should be attached to a cell
1000 // console.log("Received IOPub message not caused by one of my cells");
1001 // console.log(reply);
1002 return;
1003 }
1004 var output_types = ['stream','display_data','pyout','pyerr'];
1005 if (output_types.indexOf(msg_type) >= 0) {
1006 this.handle_output(cell, msg_type, content);
1007 } else if (msg_type === 'status') {
1008 if (content.execution_state === 'busy') {
1009 $([IPython.events]).trigger('status_busy.Kernel');
1010 } else if (content.execution_state === 'idle') {
1011 $([IPython.events]).trigger('status_idle.Kernel');
1012 } else if (content.execution_state === 'dead') {
1013 this.handle_status_dead();
1014 };
1015 } else if (msg_type === 'clear_output') {
1016 cell.clear_output(content.stdout, content.stderr, content.other);
1017 };
1018 };
1019
1020
1021 Notebook.prototype.handle_status_dead = function () {
1022 var that = this;
1023 this.kernel.stop_channels();
1024 var dialog = $('<div/>');
1025 dialog.html('The kernel has died, would you like to restart it? If you do not restart the kernel, you will be able to save the notebook, but running code will not work until the notebook is reopened.');
1026 $(document).append(dialog);
1027 dialog.dialog({
1028 resizable: false,
1029 modal: true,
1030 title: "Dead kernel",
1031 buttons : {
1032 "Restart": function () {
1033 that.start_kernel();
1034 $(this).dialog('close');
907 $(this).dialog('close');
1035 },
908 },
1036 "Continue running": function () {
909 "Continue running": function () {
@@ -1041,57 +914,6 b' var IPython = (function (IPython) {'
1041 };
914 };
1042
915
1043
916
1044 Notebook.prototype.handle_output = function (cell, msg_type, content) {
1045 var json = {};
1046 json.output_type = msg_type;
1047 if (msg_type === "stream") {
1048 json.text = content.data;
1049 json.stream = content.name;
1050 } else if (msg_type === "display_data") {
1051 json = this.convert_mime_types(json, content.data);
1052 } else if (msg_type === "pyout") {
1053 json.prompt_number = content.execution_count;
1054 json = this.convert_mime_types(json, content.data);
1055 } else if (msg_type === "pyerr") {
1056 json.ename = content.ename;
1057 json.evalue = content.evalue;
1058 json.traceback = content.traceback;
1059 };
1060 // append with dynamic=true
1061 cell.append_output(json, true);
1062 this.dirty = true;
1063 };
1064
1065
1066 Notebook.prototype.convert_mime_types = function (json, data) {
1067 if (data['text/plain'] !== undefined) {
1068 json.text = data['text/plain'];
1069 };
1070 if (data['text/html'] !== undefined) {
1071 json.html = data['text/html'];
1072 };
1073 if (data['image/svg+xml'] !== undefined) {
1074 json.svg = data['image/svg+xml'];
1075 };
1076 if (data['image/png'] !== undefined) {
1077 json.png = data['image/png'];
1078 };
1079 if (data['image/jpeg'] !== undefined) {
1080 json.jpeg = data['image/jpeg'];
1081 };
1082 if (data['text/latex'] !== undefined) {
1083 json.latex = data['text/latex'];
1084 };
1085 if (data['application/json'] !== undefined) {
1086 json.json = data['application/json'];
1087 };
1088 if (data['application/javascript'] !== undefined) {
1089 json.javascript = data['application/javascript'];
1090 }
1091 return json;
1092 };
1093
1094
1095 Notebook.prototype.execute_selected_cell = function (options) {
917 Notebook.prototype.execute_selected_cell = function (options) {
1096 // add_new: should a new cell be added if we are at the end of the nb
918 // add_new: should a new cell be added if we are at the end of the nb
1097 // terminal: execute in terminal mode, which stays in the current cell
919 // terminal: execute in terminal mode, which stays in the current cell
@@ -1101,12 +923,7 b' var IPython = (function (IPython) {'
1101 var cell = that.get_selected_cell();
923 var cell = that.get_selected_cell();
1102 var cell_index = that.find_cell_index(cell);
924 var cell_index = that.find_cell_index(cell);
1103 if (cell instanceof IPython.CodeCell) {
925 if (cell instanceof IPython.CodeCell) {
1104 cell.clear_output(true, true, true);
926 cell.execute();
1105 cell.set_input_prompt('*');
1106 cell.element.addClass("running");
1107 var code = cell.get_text();
1108 var msg_id = that.kernel.execute(cell.get_text());
1109 that.msg_cell_map[msg_id] = cell.cell_id;
1110 } else if (cell instanceof IPython.HTMLCell) {
927 } else if (cell instanceof IPython.HTMLCell) {
1111 cell.render();
928 cell.render();
1112 }
929 }
@@ -1134,37 +951,6 b' var IPython = (function (IPython) {'
1134 this.scroll_to_bottom();
951 this.scroll_to_bottom();
1135 };
952 };
1136
953
1137
1138 Notebook.prototype.request_tool_tip = function (cell,func) {
1139 // Feel free to shorten this logic if you are better
1140 // than me in regEx
1141 // basicaly you shoul be able to get xxx.xxx.xxx from
1142 // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
1143 // remove everything between matchin bracket (need to iterate)
1144 matchBracket = /\([^\(\)]+\)/g;
1145 oldfunc = func;
1146 func = func.replace(matchBracket,"");
1147 while( oldfunc != func )
1148 {
1149 oldfunc = func;
1150 func = func.replace(matchBracket,"");
1151 }
1152 // remove everythin after last open bracket
1153 endBracket = /\([^\(]*$/g;
1154 func = func.replace(endBracket,"");
1155 var re = /[a-z_][0-9a-z._]+$/gi; // casse insensitive
1156 var msg_id = this.kernel.object_info_request(re.exec(func));
1157 if(typeof(msg_id)!='undefined'){
1158 this.msg_cell_map[msg_id] = cell.cell_id;
1159 }
1160 };
1161
1162 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
1163 var msg_id = this.kernel.complete(line, cursor_pos);
1164 this.msg_cell_map[msg_id] = cell.cell_id;
1165 };
1166
1167
1168 // Persistance and loading
954 // Persistance and loading
1169
955
1170 Notebook.prototype.get_notebook_id = function () {
956 Notebook.prototype.get_notebook_id = function () {
@@ -1290,14 +1076,15 b' var IPython = (function (IPython) {'
1290
1076
1291
1077
1292 Notebook.prototype.load_notebook_success = function (data, status, xhr) {
1078 Notebook.prototype.load_notebook_success = function (data, status, xhr) {
1079 // Create the kernel before creating cells as they need to be passed it.
1080 if (! this.read_only) {
1081 this.start_kernel();
1082 }
1293 this.fromJSON(data);
1083 this.fromJSON(data);
1294 if (this.ncells() === 0) {
1084 if (this.ncells() === 0) {
1295 this.insert_cell_below('code');
1085 this.insert_cell_below('code');
1296 };
1086 };
1297 this.dirty = false;
1087 this.dirty = false;
1298 if (! this.read_only) {
1299 this.start_kernel();
1300 }
1301 this.select(0);
1088 this.select(0);
1302 this.scroll_to_top();
1089 this.scroll_to_top();
1303 if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
1090 if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
@@ -53,6 +53,23 b' var IPython = (function (IPython) {'
53 $([IPython.events]).on('status_interrupting.Kernel',function () {
53 $([IPython.events]).on('status_interrupting.Kernel',function () {
54 that.set_message("Interrupting kernel",500);
54 that.set_message("Interrupting kernel",500);
55 });
55 });
56 $([IPython.events]).on('status_dead.Kernel',function () {
57 IPython.notebook.start_kernel();
58 that.set_message("Restarting kernel",500);
59 var dialog = $('<div/>');
60 dialog.html('The kernel has died and is being restarted.');
61 $(document).append(dialog);
62 dialog.dialog({
63 resizable: false,
64 modal: true,
65 title: "Dead kernel",
66 buttons : {
67 "OK": function () {
68 $(this).dialog('close');
69 }
70 }
71 });
72 });
56 // Notebook events
73 // Notebook events
57 $([IPython.events]).on('notebook_loading.Notebook', function () {
74 $([IPython.events]).on('notebook_loading.Notebook', function () {
58 that.set_message("Loading notebook",500);
75 that.set_message("Loading notebook",500);
@@ -75,6 +75,13 b' var IPython = (function (IPython) {'
75 that.toggle();
75 that.toggle();
76 });
76 });
77
77
78 $([IPython.events]).on('open_with_text.Pager', function (event, data) {
79 if (data.text.trim() !== '') {
80 that.clear();
81 that.expand();
82 that.append_text(data.text);
83 };
84 });
78 };
85 };
79
86
80
87
@@ -13,7 +13,7 b' var IPython = (function (IPython) {'
13
13
14 // TextCell base class
14 // TextCell base class
15
15
16 var TextCell = function (notebook) {
16 var TextCell = function () {
17 this.code_mirror_mode = this.code_mirror_mode || 'htmlmixed';
17 this.code_mirror_mode = this.code_mirror_mode || 'htmlmixed';
18 IPython.Cell.apply(this, arguments);
18 IPython.Cell.apply(this, arguments);
19 this.rendered = false;
19 this.rendered = false;
@@ -176,7 +176,7 b' var IPython = (function (IPython) {'
176
176
177 // HTMLCell
177 // HTMLCell
178
178
179 var HTMLCell = function (notebook) {
179 var HTMLCell = function () {
180 this.placeholder = "Type <strong>HTML</strong> and LaTeX: $\\alpha^2$";
180 this.placeholder = "Type <strong>HTML</strong> and LaTeX: $\\alpha^2$";
181 IPython.TextCell.apply(this, arguments);
181 IPython.TextCell.apply(this, arguments);
182 this.cell_type = 'html';
182 this.cell_type = 'html';
@@ -201,7 +201,7 b' var IPython = (function (IPython) {'
201
201
202 // MarkdownCell
202 // MarkdownCell
203
203
204 var MarkdownCell = function (notebook) {
204 var MarkdownCell = function () {
205 this.placeholder = "Type *Markdown* and LaTeX: $\\alpha^2$";
205 this.placeholder = "Type *Markdown* and LaTeX: $\\alpha^2$";
206 IPython.TextCell.apply(this, arguments);
206 IPython.TextCell.apply(this, arguments);
207 this.cell_type = 'markdown';
207 this.cell_type = 'markdown';
@@ -239,7 +239,7 b' var IPython = (function (IPython) {'
239
239
240 // RawCell
240 // RawCell
241
241
242 var RawCell = function (notebook) {
242 var RawCell = function () {
243 this.placeholder = "Type plain text and LaTeX: $\\alpha^2$";
243 this.placeholder = "Type plain text and LaTeX: $\\alpha^2$";
244 this.code_mirror_mode = 'rst';
244 this.code_mirror_mode = 'rst';
245 IPython.TextCell.apply(this, arguments);
245 IPython.TextCell.apply(this, arguments);
@@ -285,7 +285,7 b' var IPython = (function (IPython) {'
285
285
286 // HTMLCell
286 // HTMLCell
287
287
288 var HeadingCell = function (notebook) {
288 var HeadingCell = function () {
289 this.placeholder = "Type Heading Here";
289 this.placeholder = "Type Heading Here";
290 IPython.TextCell.apply(this, arguments);
290 IPython.TextCell.apply(this, arguments);
291 this.cell_type = 'heading';
291 this.cell_type = 'heading';
@@ -16,8 +16,9 b' var IPython = (function (IPython) {'
16 var utils = IPython.utils;
16 var utils = IPython.utils;
17
17
18 // tooltip constructor
18 // tooltip constructor
19 var Tooltip = function (notebook) {
19 var Tooltip = function () {
20 var that = this;
20 var that = this;
21 this.time_before_tooltip = 1200;
21
22
22 // handle to html
23 // handle to html
23 this.tooltip = $('#tooltip');
24 this.tooltip = $('#tooltip');
@@ -99,10 +100,12 b' var IPython = (function (IPython) {'
99 // result as invoking `something?`
100 // result as invoking `something?`
100 Tooltip.prototype.showInPager = function()
101 Tooltip.prototype.showInPager = function()
101 {
102 {
102 var msg_id = IPython.notebook.kernel.execute(this.name+"?");
103 var that = this;
103 IPython.notebook.msg_cell_map[msg_id] = IPython.notebook.get_selected_cell().cell_id;
104 var callbacks = {'execute_reply': $.proxy(that._handle_execute_reply,that)}
104 this.remove_and_cancel_tooltip();
105 var msg_id = IPython.notebook.kernel.execute(this.name+"?", callbacks);
105 this._cmfocus();
106
107 this.remove_and_cancel_tooltip();
108 this._cmfocus();
106 }
109 }
107
110
108 // grow the tooltip verticaly
111 // grow the tooltip verticaly
@@ -152,7 +155,7 b' var IPython = (function (IPython) {'
152 Tooltip.prototype.pending = function(cell,text)
155 Tooltip.prototype.pending = function(cell,text)
153 {
156 {
154 var that = this;
157 var that = this;
155 this.tooltip_timeout = setTimeout(function(){that.request(cell)} , IPython.notebook.time_before_tooltip);
158 this.tooltip_timeout = setTimeout(function(){that.request(cell)} , that.time_before_tooltip);
156 }
159 }
157
160
158 // make an imediate completion request
161 // make an imediate completion request
@@ -203,7 +206,7 b' var IPython = (function (IPython) {'
203 return;
206 return;
204 // don't do anything if line beggin with '(' or is empty
207 // don't do anything if line beggin with '(' or is empty
205 }
208 }
206 IPython.notebook.request_tool_tip(cell, text);
209 cell.request_tooltip(text);
207 }
210 }
208
211
209 // cancel the option of having the tooltip to stick
212 // cancel the option of having the tooltip to stick
General Comments 0
You need to be logged in to leave comments. Login now