~ubuntu-branches/ubuntu/trusty/qiime/trusty

« back to all changes in this revision

Viewing changes to web/home_static/nih-cloud-apr2012/VariableRegionPositionBoundaries_files/notebook.js

  • Committer: Package Import Robot
  • Author(s): Andreas Tille
  • Date: 2013-06-17 18:28:26 UTC
  • mfrom: (9.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20130617182826-376az5ad080a0sfe
Tags: 1.7.0+dfsg-1
Upload preparations done for BioLinux to Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//----------------------------------------------------------------------------
2
 
//  Copyright (C) 2008-2011  The IPython Development Team
3
 
//
4
 
//  Distributed under the terms of the BSD License.  The full license is in
5
 
//  the file COPYING, distributed as part of this software.
6
 
//----------------------------------------------------------------------------
7
 
 
8
 
//============================================================================
9
 
// Notebook
10
 
//============================================================================
11
 
 
12
 
var IPython = (function (IPython) {
13
 
 
14
 
    var utils = IPython.utils;
15
 
 
16
 
    var Notebook = function (selector) {
17
 
        this.read_only = IPython.read_only;
18
 
        this.element = $(selector);
19
 
        this.element.scroll();
20
 
        this.element.data("notebook", this);
21
 
        this.next_prompt_number = 1;
22
 
        this.kernel = null;
23
 
        this.clipboard = null;
24
 
        this.paste_enabled = false;
25
 
        this.dirty = false;
26
 
        this.msg_cell_map = {};
27
 
        this.metadata = {};
28
 
        this.control_key_active = false;
29
 
        this.notebook_id = null;
30
 
        this.notebook_name = null;
31
 
        this.notebook_name_blacklist_re = /[\/\\]/;
32
 
        this.nbformat = 3 // Increment this when changing the nbformat
33
 
        this.style();
34
 
        this.create_elements();
35
 
        this.bind_events();
36
 
        this.set_tooltipontab(true);
37
 
        this.set_smartcompleter(true);
38
 
        this.set_timebeforetooltip(1200);
39
 
    };
40
 
 
41
 
 
42
 
    Notebook.prototype.style = function () {
43
 
        $('div#notebook').addClass('border-box-sizing');
44
 
    };
45
 
 
46
 
 
47
 
    Notebook.prototype.create_elements = function () {
48
 
        // We add this end_space div to the end of the notebook div to:
49
 
        // i) provide a margin between the last cell and the end of the notebook
50
 
        // ii) to prevent the div from scrolling up when the last cell is being
51
 
        // edited, but is too low on the page, which browsers will do automatically.
52
 
        var that = this;
53
 
        var end_space = $('<div/>').addClass('end_space').height("30%");
54
 
        end_space.dblclick(function (e) {
55
 
            if (that.read_only) return;
56
 
            var ncells = that.ncells();
57
 
            that.insert_cell_below('code',ncells-1);
58
 
        });
59
 
        this.element.append(end_space);
60
 
        $('div#notebook').addClass('border-box-sizing');
61
 
    };
62
 
 
63
 
 
64
 
    Notebook.prototype.bind_events = function () {
65
 
        var that = this;
66
 
        $(document).keydown(function (event) {
67
 
            // console.log(event);
68
 
            if (that.read_only) return true;
69
 
            
70
 
            // Save (CTRL+S) or (AppleKey+S) 
71
 
            //metaKey = applekey on mac
72
 
            if ((event.ctrlKey || event.metaKey) && event.keyCode==83) { 
73
 
                that.save_notebook();
74
 
                event.preventDefault();
75
 
                return false;
76
 
            } else if (event.which === 27) {
77
 
                // Intercept escape at highest level to avoid closing 
78
 
                // websocket connection with firefox
79
 
                event.preventDefault();
80
 
            }
81
 
            if (event.which === 38 && !event.shiftKey) {
82
 
                var cell = that.get_selected_cell();
83
 
                if (cell.at_top()) {
84
 
                    event.preventDefault();
85
 
                    that.select_prev();
86
 
                };
87
 
            } else if (event.which === 40 && !event.shiftKey) {
88
 
                var cell = that.get_selected_cell();
89
 
                if (cell.at_bottom()) {
90
 
                    event.preventDefault();
91
 
                    that.select_next();
92
 
                };
93
 
            } else if (event.which === 13 && event.shiftKey) {
94
 
                that.execute_selected_cell();
95
 
                return false;
96
 
            } else if (event.which === 13 && event.ctrlKey) {
97
 
                that.execute_selected_cell({terminal:true});
98
 
                return false;
99
 
            } else if (event.which === 77 && event.ctrlKey && that.control_key_active == false) {
100
 
                that.control_key_active = true;
101
 
                return false;
102
 
            } else if (event.which === 88 && that.control_key_active) {
103
 
                // Cut selected cell = x
104
 
                that.cut_cell();
105
 
                that.control_key_active = false;
106
 
                return false;
107
 
            } else if (event.which === 67 && that.control_key_active) {
108
 
                // Copy selected cell = c
109
 
                that.copy_cell();
110
 
                that.control_key_active = false;
111
 
                return false;
112
 
            } else if (event.which === 86 && that.control_key_active) {
113
 
                // Paste selected cell = v
114
 
                that.paste_cell();
115
 
                that.control_key_active = false;
116
 
                return false;
117
 
            } else if (event.which === 68 && that.control_key_active) {
118
 
                // Delete selected cell = d
119
 
                that.delete_cell();
120
 
                that.control_key_active = false;
121
 
                return false;
122
 
            } else if (event.which === 65 && that.control_key_active) {
123
 
                // Insert code cell above selected = a
124
 
                that.insert_cell_above('code');
125
 
                that.control_key_active = false;
126
 
                return false;
127
 
            } else if (event.which === 66 && that.control_key_active) {
128
 
                // Insert code cell below selected = b
129
 
                that.insert_cell_below('code');
130
 
                that.control_key_active = false;
131
 
                return false;
132
 
            } else if (event.which === 89 && that.control_key_active) {
133
 
                // To code = y
134
 
                that.to_code();
135
 
                that.control_key_active = false;
136
 
                return false;
137
 
            } else if (event.which === 77 && that.control_key_active) {
138
 
                // To markdown = m
139
 
                that.to_markdown();
140
 
                that.control_key_active = false;
141
 
                return false;
142
 
            } else if (event.which === 84 && that.control_key_active) {
143
 
                // To Plaintext = t
144
 
                that.to_plaintext();
145
 
                that.control_key_active = false;
146
 
                return false;
147
 
            } else if (event.which === 49 && that.control_key_active) {
148
 
                // To Heading 1 = 1
149
 
                that.to_heading(undefined, 1);
150
 
                that.control_key_active = false;
151
 
                return false;
152
 
            } else if (event.which === 50 && that.control_key_active) {
153
 
                // To Heading 2 = 2
154
 
                that.to_heading(undefined, 2);
155
 
                that.control_key_active = false;
156
 
                return false;
157
 
            } else if (event.which === 51 && that.control_key_active) {
158
 
                // To Heading 3 = 3
159
 
                that.to_heading(undefined, 3);
160
 
                that.control_key_active = false;
161
 
                return false;
162
 
            } else if (event.which === 52 && that.control_key_active) {
163
 
                // To Heading 4 = 4
164
 
                that.to_heading(undefined, 4);
165
 
                that.control_key_active = false;
166
 
                return false;
167
 
            } else if (event.which === 53 && that.control_key_active) {
168
 
                // To Heading 5 = 5
169
 
                that.to_heading(undefined, 5);
170
 
                that.control_key_active = false;
171
 
                return false;
172
 
            } else if (event.which === 54 && that.control_key_active) {
173
 
                // To Heading 6 = 6
174
 
                that.to_heading(undefined, 6);
175
 
                that.control_key_active = false;
176
 
                return false;
177
 
            } else if (event.which === 79 && that.control_key_active) {
178
 
                // Toggle output = o
179
 
                that.toggle_output();
180
 
                that.control_key_active = false;
181
 
                return false;
182
 
            } else if (event.which === 83 && that.control_key_active) {
183
 
                // Save notebook = s
184
 
                that.save_notebook();
185
 
                that.control_key_active = false;
186
 
                return false;
187
 
            } else if (event.which === 74 && that.control_key_active) {
188
 
                // Move cell down = j
189
 
                that.move_cell_down();
190
 
                that.control_key_active = false;
191
 
                return false;
192
 
            } else if (event.which === 75 && that.control_key_active) {
193
 
                // Move cell up = k
194
 
                that.move_cell_up();
195
 
                that.control_key_active = false;
196
 
                return false;
197
 
            } else if (event.which === 80 && that.control_key_active) {
198
 
                // Select previous = p
199
 
                that.select_prev();
200
 
                that.control_key_active = false;
201
 
                return false;
202
 
            } else if (event.which === 78 && that.control_key_active) {
203
 
                // Select next = n
204
 
                that.select_next();
205
 
                that.control_key_active = false;
206
 
                return false;
207
 
            } else if (event.which === 76 && that.control_key_active) {
208
 
                // Toggle line numbers = l
209
 
                that.cell_toggle_line_numbers();
210
 
                that.control_key_active = false;
211
 
                return false;
212
 
            } else if (event.which === 73 && that.control_key_active) {
213
 
                // Interrupt kernel = i
214
 
                that.kernel.interrupt();
215
 
                that.control_key_active = false;
216
 
                return false;
217
 
            } else if (event.which === 190 && that.control_key_active) {
218
 
                // Restart kernel = .  # matches qt console
219
 
                that.restart_kernel();
220
 
                that.control_key_active = false;
221
 
                return false;
222
 
            } else if (event.which === 72 && that.control_key_active) {
223
 
                // Show keyboard shortcuts = h
224
 
                IPython.quick_help.show_keyboard_shortcuts();
225
 
                that.control_key_active = false;
226
 
                return false;
227
 
            } else if (that.control_key_active) {
228
 
                that.control_key_active = false;
229
 
                return true;
230
 
            };
231
 
            return true;
232
 
        });
233
 
 
234
 
        this.element.bind('collapse_pager', function () {
235
 
            var app_height = $('div#main_app').height(); // content height
236
 
            var splitter_height = $('div#pager_splitter').outerHeight(true);
237
 
            var new_height = app_height - splitter_height;
238
 
            that.element.animate({height : new_height + 'px'}, 'fast');
239
 
        });
240
 
 
241
 
        this.element.bind('expand_pager', function () {
242
 
            var app_height = $('div#main_app').height(); // content height
243
 
            var splitter_height = $('div#pager_splitter').outerHeight(true);
244
 
            var pager_height = $('div#pager').outerHeight(true);
245
 
            var new_height = app_height - pager_height - splitter_height; 
246
 
            that.element.animate({height : new_height + 'px'}, 'fast');
247
 
        });
248
 
 
249
 
        $(window).bind('beforeunload', function () {
250
 
            // TODO: Make killing the kernel configurable.
251
 
            var kill_kernel = false;
252
 
            if (kill_kernel) {
253
 
                that.kernel.kill();
254
 
            }
255
 
            if (that.dirty && ! that.read_only) {
256
 
                return "You have unsaved changes that will be lost if you leave this page.";
257
 
            };
258
 
            // Null is the *only* return value that will make the browser not
259
 
            // pop up the "don't leave" dialog.
260
 
            return null;
261
 
        });
262
 
    };
263
 
 
264
 
 
265
 
    Notebook.prototype.scroll_to_bottom = function () {
266
 
        this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
267
 
    };
268
 
 
269
 
 
270
 
    Notebook.prototype.scroll_to_top = function () {
271
 
        this.element.animate({scrollTop:0}, 0);
272
 
    };
273
 
 
274
 
 
275
 
    // Cell indexing, retrieval, etc.
276
 
 
277
 
    Notebook.prototype.get_cell_elements = function () {
278
 
        return this.element.children("div.cell");
279
 
    };
280
 
 
281
 
 
282
 
    Notebook.prototype.get_cell_element = function (index) {
283
 
        var result = null;
284
 
        var e = this.get_cell_elements().eq(index);
285
 
        if (e.length !== 0) {
286
 
            result = e;
287
 
        }
288
 
        return result;
289
 
    };
290
 
 
291
 
 
292
 
    Notebook.prototype.ncells = function (cell) {
293
 
        return this.get_cell_elements().length;
294
 
    };
295
 
 
296
 
 
297
 
    // TODO: we are often calling cells as cells()[i], which we should optimize
298
 
    // to cells(i) or a new method.
299
 
    Notebook.prototype.get_cells = function () {
300
 
        return this.get_cell_elements().toArray().map(function (e) {
301
 
            return $(e).data("cell");
302
 
        });
303
 
    };
304
 
 
305
 
 
306
 
    Notebook.prototype.get_cell = function (index) {
307
 
        var result = null;
308
 
        var ce = this.get_cell_element(index);
309
 
        if (ce !== null) {
310
 
            result = ce.data('cell');
311
 
        }
312
 
        return result;
313
 
    }
314
 
 
315
 
 
316
 
    Notebook.prototype.get_next_cell = function (cell) {
317
 
        var result = null;
318
 
        var index = this.find_cell_index(cell);
319
 
        if (index !== null && index < this.ncells()) {
320
 
            result = this.get_cell(index+1);
321
 
        }
322
 
        return result;
323
 
    }
324
 
 
325
 
 
326
 
    Notebook.prototype.get_prev_cell = function (cell) {
327
 
        var result = null;
328
 
        var index = this.find_cell_index(cell);
329
 
        if (index !== null && index > 1) {
330
 
            result = this.get_cell(index-1);
331
 
        }
332
 
        return result;
333
 
    }
334
 
 
335
 
    Notebook.prototype.find_cell_index = function (cell) {
336
 
        var result = null;
337
 
        this.get_cell_elements().filter(function (index) {
338
 
            if ($(this).data("cell") === cell) {
339
 
                result = index;
340
 
            };
341
 
        });
342
 
        return result;
343
 
    };
344
 
 
345
 
 
346
 
    Notebook.prototype.index_or_selected = function (index) {
347
 
        var i;
348
 
        if (index === undefined || index === null) {
349
 
            i = this.get_selected_index();
350
 
            if (i === null) {
351
 
                i = 0;
352
 
            }
353
 
        } else {
354
 
            i = index;
355
 
        }
356
 
        return i;
357
 
    };
358
 
 
359
 
 
360
 
    Notebook.prototype.get_selected_cell = function () {
361
 
        var index = this.get_selected_index();
362
 
        return this.get_cell(index);
363
 
    };
364
 
 
365
 
 
366
 
    Notebook.prototype.is_valid_cell_index = function (index) {
367
 
        if (index !== null && index >= 0 && index < this.ncells()) {
368
 
            return true;
369
 
        } else {
370
 
            return false;
371
 
        };
372
 
    }
373
 
 
374
 
    Notebook.prototype.get_selected_index = function () {
375
 
        var result = null;
376
 
        this.get_cell_elements().filter(function (index) {
377
 
            if ($(this).data("cell").selected === true) {
378
 
                result = index;
379
 
            };
380
 
        });
381
 
        return result;
382
 
    };
383
 
 
384
 
 
385
 
    Notebook.prototype.cell_for_msg = function (msg_id) {
386
 
        var cell_id = this.msg_cell_map[msg_id];
387
 
        var result = null;
388
 
        this.get_cell_elements().filter(function (index) {
389
 
            cell = $(this).data("cell");
390
 
            if (cell.cell_id === cell_id) {
391
 
                result = cell;
392
 
            };
393
 
        });
394
 
        return result;
395
 
    };
396
 
 
397
 
 
398
 
    // Cell selection.
399
 
 
400
 
    Notebook.prototype.select = function (index) {
401
 
        if (index !== undefined && index >= 0 && index < this.ncells()) {
402
 
            sindex = this.get_selected_index()
403
 
            if (sindex !== null && index !== sindex) {
404
 
                this.get_cell(sindex).unselect();
405
 
            };
406
 
            var cell = this.get_cell(index)
407
 
            cell.select();
408
 
            if (cell.cell_type === 'heading') {
409
 
                $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
410
 
                    {'cell_type':cell.cell_type,level:cell.level}
411
 
                );
412
 
            } else {
413
 
                $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
414
 
                    {'cell_type':cell.cell_type}
415
 
                );
416
 
            };
417
 
        };
418
 
        return this;
419
 
    };
420
 
 
421
 
 
422
 
    Notebook.prototype.select_next = function () {
423
 
        var index = this.get_selected_index();
424
 
        if (index !== null && index >= 0 && (index+1) < this.ncells()) {
425
 
            this.select(index+1);
426
 
        };
427
 
        return this;
428
 
    };
429
 
 
430
 
 
431
 
    Notebook.prototype.select_prev = function () {
432
 
        var index = this.get_selected_index();
433
 
        if (index !== null && index >= 0 && (index-1) < this.ncells()) {
434
 
            this.select(index-1);
435
 
        };
436
 
        return this;
437
 
    };
438
 
 
439
 
 
440
 
    // Cell movement
441
 
 
442
 
    Notebook.prototype.move_cell_up = function (index) {
443
 
        var i = this.index_or_selected();
444
 
        if (i !== null && i < this.ncells() && i > 0) {
445
 
            var pivot = this.get_cell_element(i-1);
446
 
            var tomove = this.get_cell_element(i);
447
 
            if (pivot !== null && tomove !== null) {
448
 
                tomove.detach();
449
 
                pivot.before(tomove);
450
 
                this.select(i-1);
451
 
            };
452
 
        };
453
 
        this.dirty = true;
454
 
        return this;
455
 
    };
456
 
 
457
 
 
458
 
    Notebook.prototype.move_cell_down = function (index) {
459
 
        var i = this.index_or_selected();
460
 
        if (i !== null && i < (this.ncells()-1) && i >= 0) {
461
 
            var pivot = this.get_cell_element(i+1);
462
 
            var tomove = this.get_cell_element(i);
463
 
            if (pivot !== null && tomove !== null) {
464
 
                tomove.detach();
465
 
                pivot.after(tomove);
466
 
                this.select(i+1);
467
 
            };
468
 
        };
469
 
        this.dirty = true;
470
 
        return this;
471
 
    };
472
 
 
473
 
 
474
 
    Notebook.prototype.sort_cells = function () {
475
 
        // This is not working right now. Calling this will actually crash
476
 
        // the browser. I think there is an infinite loop in here...
477
 
        var ncells = this.ncells();
478
 
        var sindex = this.get_selected_index();
479
 
        var swapped;
480
 
        do {
481
 
            swapped = false;
482
 
            for (var i=1; i<ncells; i++) {
483
 
                current = this.get_cell(i);
484
 
                previous = this.get_cell(i-1);
485
 
                if (previous.input_prompt_number > current.input_prompt_number) {
486
 
                    this.move_cell_up(i);
487
 
                    swapped = true;
488
 
                };
489
 
            };
490
 
        } while (swapped);
491
 
        this.select(sindex);
492
 
        return this;
493
 
    };
494
 
 
495
 
    // Insertion, deletion.
496
 
 
497
 
    Notebook.prototype.delete_cell = function (index) {
498
 
        var i = this.index_or_selected(index);
499
 
        if (this.is_valid_cell_index(i)) {
500
 
            var ce = this.get_cell_element(i);
501
 
            ce.remove();
502
 
            if (i === (this.ncells())) {
503
 
                this.select(i-1);
504
 
            } else {
505
 
                this.select(i);
506
 
            };
507
 
            this.dirty = true;
508
 
        };
509
 
        return this;
510
 
    };
511
 
 
512
 
 
513
 
    Notebook.prototype.insert_cell_below = function (type, index) {
514
 
        // type = ('code','html','markdown')
515
 
        // index = cell index or undefined to insert below selected
516
 
        index = this.index_or_selected(index);
517
 
        var cell = null;
518
 
        if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
519
 
            if (type === 'code') {
520
 
                cell = new IPython.CodeCell(this);
521
 
                cell.set_input_prompt();
522
 
            } else if (type === 'markdown') {
523
 
                cell = new IPython.MarkdownCell(this);
524
 
            } else if (type === 'html') {
525
 
                cell = new IPython.HTMLCell(this);
526
 
            } else if (type === 'plaintext') {
527
 
                cell = new IPython.PlaintextCell(this);
528
 
            } else if (type === 'heading') {
529
 
                cell = new IPython.HeadingCell(this);
530
 
            };
531
 
            if (cell !== null) {
532
 
                if (this.ncells() === 0) {
533
 
                    this.element.find('div.end_space').before(cell.element);
534
 
                } else if (this.is_valid_cell_index(index)) {
535
 
                    this.get_cell_element(index).after(cell.element);
536
 
                };
537
 
                cell.render();
538
 
                this.select(this.find_cell_index(cell));
539
 
                this.dirty = true;
540
 
                return cell;
541
 
            };
542
 
        };
543
 
        return cell;
544
 
    };
545
 
 
546
 
 
547
 
    Notebook.prototype.insert_cell_above = function (type, index) {
548
 
        // type = ('code','html','markdown')
549
 
        // index = cell index or undefined to insert above selected
550
 
        index = this.index_or_selected(index);
551
 
        var cell = null;
552
 
        if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
553
 
            if (type === 'code') {
554
 
                cell = new IPython.CodeCell(this);
555
 
                cell.set_input_prompt();
556
 
            } else if (type === 'markdown') {
557
 
                cell = new IPython.MarkdownCell(this);
558
 
            } else if (type === 'html') {
559
 
                cell = new IPython.HTMLCell(this);
560
 
            } else if (type === 'plaintext') {
561
 
                cell = new IPython.PlaintextCell(this);
562
 
            } else if (type === 'heading') {
563
 
                cell = new IPython.HeadingCell(this);
564
 
            };
565
 
            if (cell !== null) {
566
 
                if (this.ncells() === 0) {
567
 
                    this.element.find('div.end_space').before(cell.element);
568
 
                } else if (this.is_valid_cell_index(index)) {
569
 
                    this.get_cell_element(index).before(cell.element);
570
 
                };
571
 
                cell.render();
572
 
                this.select(this.find_cell_index(cell));
573
 
                this.dirty = true;
574
 
                return cell;
575
 
            };
576
 
        };
577
 
        return cell;
578
 
    };
579
 
 
580
 
 
581
 
    Notebook.prototype.to_code = function (index) {
582
 
        var i = this.index_or_selected(index);
583
 
        if (this.is_valid_cell_index(i)) {
584
 
            var source_element = this.get_cell_element(i);
585
 
            var source_cell = source_element.data("cell");
586
 
            if (!(source_cell instanceof IPython.CodeCell)) {
587
 
                target_cell = this.insert_cell_below('code',i);
588
 
                var text = source_cell.get_text();
589
 
                if (text === source_cell.placeholder) {
590
 
                    text = '';
591
 
                }
592
 
                target_cell.set_text(text);
593
 
                source_element.remove();
594
 
                this.dirty = true;
595
 
            };
596
 
        };
597
 
    };
598
 
 
599
 
 
600
 
    Notebook.prototype.to_markdown = function (index) {
601
 
        var i = this.index_or_selected(index);
602
 
        if (this.is_valid_cell_index(i)) {
603
 
            var source_element = this.get_cell_element(i);
604
 
            var source_cell = source_element.data("cell");
605
 
            if (!(source_cell instanceof IPython.MarkdownCell)) {
606
 
                target_cell = this.insert_cell_below('markdown',i);
607
 
                var text = source_cell.get_text();
608
 
                if (text === source_cell.placeholder) {
609
 
                    text = '';
610
 
                };
611
 
                // The edit must come before the set_text.
612
 
                target_cell.edit();
613
 
                target_cell.set_text(text);
614
 
                source_element.remove();
615
 
                this.dirty = true;
616
 
            };
617
 
        };
618
 
    };
619
 
 
620
 
 
621
 
    Notebook.prototype.to_html = function (index) {
622
 
        var i = this.index_or_selected(index);
623
 
        if (this.is_valid_cell_index(i)) {
624
 
            var source_element = this.get_cell_element(i);
625
 
            var source_cell = source_element.data("cell");
626
 
            var target_cell = null;
627
 
            if (!(source_cell instanceof IPython.HTMLCell)) {
628
 
                target_cell = this.insert_cell_below('html',i);
629
 
                var text = source_cell.get_text();
630
 
                if (text === source_cell.placeholder) {
631
 
                    text = '';
632
 
                };
633
 
                // The edit must come before the set_text.
634
 
                target_cell.edit();
635
 
                target_cell.set_text(text);
636
 
                source_element.remove();
637
 
                this.dirty = true;
638
 
            };
639
 
        };
640
 
    };
641
 
 
642
 
 
643
 
    Notebook.prototype.to_plaintext = function (index) {
644
 
        var i = this.index_or_selected(index);
645
 
        if (this.is_valid_cell_index(i)) {
646
 
            var source_element = this.get_cell_element(i);
647
 
            var source_cell = source_element.data("cell");
648
 
            var target_cell = null;
649
 
            if (!(source_cell instanceof IPython.PlaintextCell)) {
650
 
                target_cell = this.insert_cell_below('plaintext',i);
651
 
                var text = source_cell.get_text();
652
 
                if (text === source_cell.placeholder) {
653
 
                    text = '';
654
 
                };
655
 
                // The edit must come before the set_text.
656
 
                target_cell.edit();
657
 
                target_cell.set_text(text);
658
 
                source_element.remove();
659
 
                this.dirty = true;
660
 
            };
661
 
        };
662
 
    };
663
 
 
664
 
 
665
 
    Notebook.prototype.to_heading = function (index, level) {
666
 
        level = level || 1;
667
 
        var i = this.index_or_selected(index);
668
 
        if (this.is_valid_cell_index(i)) {
669
 
            var source_element = this.get_cell_element(i);
670
 
            var source_cell = source_element.data("cell");
671
 
            var target_cell = null;
672
 
            if (source_cell instanceof IPython.HeadingCell) {
673
 
                source_cell.set_level(level);
674
 
            } else {
675
 
                target_cell = this.insert_cell_below('heading',i);
676
 
                var text = source_cell.get_text();
677
 
                if (text === source_cell.placeholder) {
678
 
                    text = '';
679
 
                };
680
 
                // The edit must come before the set_text.
681
 
                target_cell.set_level(level);
682
 
                target_cell.edit();
683
 
                target_cell.set_text(text);
684
 
                source_element.remove();
685
 
                this.dirty = true;
686
 
            };
687
 
            $([IPython.events]).trigger('selected_cell_type_changed.Notebook',
688
 
                {'cell_type':'heading',level:level}
689
 
            );
690
 
        };
691
 
    };
692
 
 
693
 
 
694
 
    // Cut/Copy/Paste
695
 
 
696
 
    Notebook.prototype.enable_paste = function () {
697
 
        var that = this;
698
 
        if (!this.paste_enabled) {
699
 
            $('#paste_cell').removeClass('ui-state-disabled')
700
 
                .on('click', function () {that.paste_cell();});
701
 
            $('#paste_cell_above').removeClass('ui-state-disabled')
702
 
                .on('click', function () {that.paste_cell_above();});
703
 
            $('#paste_cell_below').removeClass('ui-state-disabled')
704
 
                .on('click', function () {that.paste_cell_below();});
705
 
            this.paste_enabled = true;
706
 
        };
707
 
    };
708
 
 
709
 
 
710
 
    Notebook.prototype.disable_paste = function () {
711
 
        if (this.paste_enabled) {
712
 
            $('#paste_cell').addClass('ui-state-disabled').off('click');
713
 
            $('#paste_cell_above').addClass('ui-state-disabled').off('click');
714
 
            $('#paste_cell_below').addClass('ui-state-disabled').off('click');
715
 
            this.paste_enabled = false;
716
 
        };
717
 
    };
718
 
 
719
 
 
720
 
    Notebook.prototype.cut_cell = function () {
721
 
        this.copy_cell();
722
 
        this.delete_cell();
723
 
    }
724
 
 
725
 
    Notebook.prototype.copy_cell = function () {
726
 
        var cell = this.get_selected_cell();
727
 
        this.clipboard = cell.toJSON();
728
 
        this.enable_paste();
729
 
    };
730
 
 
731
 
 
732
 
    Notebook.prototype.paste_cell = function () {
733
 
        if (this.clipboard !== null && this.paste_enabled) {
734
 
            var cell_data = this.clipboard;
735
 
            var new_cell = this.insert_cell_above(cell_data.cell_type);
736
 
            new_cell.fromJSON(cell_data);
737
 
            old_cell = this.get_next_cell(new_cell);
738
 
            this.delete_cell(this.find_cell_index(old_cell));
739
 
            this.select(this.find_cell_index(new_cell));
740
 
        };
741
 
    };
742
 
 
743
 
 
744
 
    Notebook.prototype.paste_cell_above = function () {
745
 
        if (this.clipboard !== null && this.paste_enabled) {
746
 
            var cell_data = this.clipboard;
747
 
            var new_cell = this.insert_cell_above(cell_data.cell_type);
748
 
            new_cell.fromJSON(cell_data);
749
 
        };
750
 
    };
751
 
 
752
 
 
753
 
    Notebook.prototype.paste_cell_below = function () {
754
 
        if (this.clipboard !== null && this.paste_enabled) {
755
 
            var cell_data = this.clipboard;
756
 
            var new_cell = this.insert_cell_below(cell_data.cell_type);
757
 
            new_cell.fromJSON(cell_data);
758
 
        };
759
 
    };
760
 
 
761
 
 
762
 
    // Split/merge
763
 
 
764
 
    Notebook.prototype.split_cell = function () {
765
 
        // Todo: implement spliting for other cell types.
766
 
        var cell = this.get_selected_cell();
767
 
        if (cell.is_splittable()) {
768
 
            texta = cell.get_pre_cursor();
769
 
            textb = cell.get_post_cursor();
770
 
            if (cell instanceof IPython.CodeCell) {
771
 
                cell.set_text(texta);
772
 
                var new_cell = this.insert_cell_below('code');
773
 
                new_cell.set_text(textb);
774
 
            } else if (cell instanceof IPython.MarkdownCell) {
775
 
                cell.set_text(texta);
776
 
                cell.render();
777
 
                var new_cell = this.insert_cell_below('markdown');
778
 
                new_cell.edit(); // editor must be visible to call set_text
779
 
                new_cell.set_text(textb);
780
 
                new_cell.render();
781
 
            } else if (cell instanceof IPython.HTMLCell) {
782
 
                cell.set_text(texta);
783
 
                cell.render();
784
 
                var new_cell = this.insert_cell_below('html');
785
 
                new_cell.edit(); // editor must be visible to call set_text
786
 
                new_cell.set_text(textb);
787
 
                new_cell.render();
788
 
            };
789
 
        };
790
 
    };
791
 
 
792
 
 
793
 
    Notebook.prototype.merge_cell_above = function () {
794
 
        var index = this.get_selected_index();
795
 
        var cell = this.get_cell(index);
796
 
        if (index > 0) {
797
 
            upper_cell = this.get_cell(index-1);
798
 
            upper_text = upper_cell.get_text();
799
 
            text = cell.get_text();
800
 
            if (cell instanceof IPython.CodeCell) {
801
 
                cell.set_text(upper_text+'\n'+text);
802
 
            } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
803
 
                cell.edit();
804
 
                cell.set_text(upper_text+'\n'+text);
805
 
                cell.render();
806
 
            };
807
 
            this.delete_cell(index-1);
808
 
            this.select(this.find_cell_index(cell));
809
 
        };
810
 
    };
811
 
 
812
 
 
813
 
    Notebook.prototype.merge_cell_below = function () {
814
 
        var index = this.get_selected_index();
815
 
        var cell = this.get_cell(index);
816
 
        if (index < this.ncells()-1) {
817
 
            lower_cell = this.get_cell(index+1);
818
 
            lower_text = lower_cell.get_text();
819
 
            text = cell.get_text();
820
 
            if (cell instanceof IPython.CodeCell) {
821
 
                cell.set_text(text+'\n'+lower_text);
822
 
            } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
823
 
                cell.edit();
824
 
                cell.set_text(text+'\n'+lower_text);
825
 
                cell.render();
826
 
            };
827
 
            this.delete_cell(index+1);
828
 
            this.select(this.find_cell_index(cell));
829
 
        };
830
 
    };
831
 
 
832
 
 
833
 
    // Cell collapsing and output clearing
834
 
 
835
 
    Notebook.prototype.collapse = function (index) {
836
 
        var i = this.index_or_selected(index);
837
 
        this.get_cell(i).collapse();
838
 
        this.dirty = true;
839
 
    };
840
 
 
841
 
 
842
 
    Notebook.prototype.expand = function (index) {
843
 
        var i = this.index_or_selected(index);
844
 
        this.get_cell(i).expand();
845
 
        this.dirty = true;
846
 
    };
847
 
 
848
 
 
849
 
    Notebook.prototype.toggle_output = function (index) {
850
 
        var i = this.index_or_selected(index);
851
 
        this.get_cell(i).toggle_output();
852
 
        this.dirty = true;
853
 
    };
854
 
 
855
 
 
856
 
    Notebook.prototype.set_timebeforetooltip = function (time) {
857
 
        this.time_before_tooltip = time;
858
 
    };
859
 
 
860
 
 
861
 
    Notebook.prototype.set_tooltipontab = function (state) {
862
 
        this.tooltip_on_tab = state;
863
 
    };
864
 
 
865
 
 
866
 
    Notebook.prototype.set_smartcompleter = function (state) {
867
 
        this.smart_completer = state;
868
 
    };
869
 
 
870
 
 
871
 
    Notebook.prototype.clear_all_output = function () {
872
 
        var ncells = this.ncells();
873
 
        var cells = this.get_cells();
874
 
        for (var i=0; i<ncells; i++) {
875
 
            if (cells[i] instanceof IPython.CodeCell) {
876
 
                cells[i].clear_output(true,true,true);
877
 
            }
878
 
        };
879
 
        this.dirty = true;
880
 
    };
881
 
 
882
 
 
883
 
    // Other cell functions: line numbers, ...
884
 
 
885
 
    Notebook.prototype.cell_toggle_line_numbers = function() {
886
 
        this.get_selected_cell().toggle_line_numbers();
887
 
    };
888
 
 
889
 
    // Kernel related things
890
 
 
891
 
    Notebook.prototype.start_kernel = function () {
892
 
        this.kernel = new IPython.Kernel();
893
 
        this.kernel.start(this.notebook_id, $.proxy(this.kernel_started, this));
894
 
    };
895
 
 
896
 
 
897
 
    Notebook.prototype.restart_kernel = function () {
898
 
        var that = this;
899
 
        var dialog = $('<div/>');
900
 
        dialog.html('Do you want to restart the current kernel?  You will lose all variables defined in it.');
901
 
        $(document).append(dialog);
902
 
        dialog.dialog({
903
 
            resizable: false,
904
 
            modal: true,
905
 
            title: "Restart kernel or continue running?",
906
 
            closeText: '',
907
 
            buttons : {
908
 
                "Restart": function () {
909
 
                    that.kernel.restart($.proxy(that.kernel_started, that));
910
 
                    $(this).dialog('close');
911
 
                },
912
 
                "Continue running": function () {
913
 
                    $(this).dialog('close');
914
 
                }
915
 
            }
916
 
        });
917
 
    };
918
 
 
919
 
 
920
 
    Notebook.prototype.kernel_started = function () {
921
 
        console.log("Kernel started: ", this.kernel.kernel_id);
922
 
        this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
923
 
        this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
924
 
    };
925
 
 
926
 
 
927
 
    Notebook.prototype.handle_shell_reply = function (e) {
928
 
        reply = $.parseJSON(e.data);
929
 
        var header = reply.header;
930
 
        var content = reply.content;
931
 
        var msg_type = header.msg_type;
932
 
        // console.log(reply);
933
 
        var cell = this.cell_for_msg(reply.parent_header.msg_id);
934
 
        if (msg_type === "execute_reply") {
935
 
            cell.set_input_prompt(content.execution_count);
936
 
            cell.element.removeClass("running");
937
 
            this.dirty = true;
938
 
        } else if (msg_type === "complete_reply") {
939
 
            cell.finish_completing(content.matched_text, content.matches);
940
 
        } else if (msg_type === "object_info_reply"){
941
 
            //console.log('back from object_info_request : ')
942
 
            rep = reply.content;
943
 
            if(rep.found)
944
 
            {
945
 
                cell.finish_tooltip(rep);
946
 
            }
947
 
        } else {
948
 
          //console.log("unknown reply:"+msg_type);
949
 
        }
950
 
        // when having a rely from object_info_reply,
951
 
        // no payload so no nned to handle it
952
 
        if(typeof(content.payload)!='undefined') {
953
 
            var payload = content.payload || [];
954
 
            this.handle_payload(cell, payload);
955
 
        }
956
 
    };
957
 
 
958
 
 
959
 
    Notebook.prototype.handle_payload = function (cell, payload) {
960
 
        var l = payload.length;
961
 
        for (var i=0; i<l; i++) {
962
 
            if (payload[i].source === 'IPython.zmq.page.page') {
963
 
                if (payload[i].text.trim() !== '') {
964
 
                    IPython.pager.clear();
965
 
                    IPython.pager.expand();
966
 
                    IPython.pager.append_text(payload[i].text);
967
 
                }
968
 
            } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
969
 
                var index = this.find_cell_index(cell);
970
 
                var new_cell = this.insert_cell_below('code',index);
971
 
                new_cell.set_text(payload[i].text);
972
 
                this.dirty = true;
973
 
            }
974
 
        };
975
 
    };
976
 
 
977
 
 
978
 
    Notebook.prototype.handle_iopub_reply = function (e) {
979
 
        reply = $.parseJSON(e.data);
980
 
        var content = reply.content;
981
 
        // console.log(reply);
982
 
        var msg_type = reply.header.msg_type;
983
 
        var cell = this.cell_for_msg(reply.parent_header.msg_id);
984
 
        if (msg_type !== 'status' && !cell){
985
 
            // message not from this notebook, but should be attached to a cell
986
 
            // console.log("Received IOPub message not caused by one of my cells");
987
 
            // console.log(reply);
988
 
            return;
989
 
        }
990
 
        var output_types = ['stream','display_data','pyout','pyerr'];
991
 
        if (output_types.indexOf(msg_type) >= 0) {
992
 
            this.handle_output(cell, msg_type, content);
993
 
        } else if (msg_type === 'status') {
994
 
            if (content.execution_state === 'busy') {
995
 
                $([IPython.events]).trigger('status_busy.Kernel');
996
 
            } else if (content.execution_state === 'idle') {
997
 
                $([IPython.events]).trigger('status_idle.Kernel');
998
 
            } else if (content.execution_state === 'dead') {
999
 
                this.handle_status_dead();
1000
 
            };
1001
 
        } else if (msg_type === 'clear_output') {
1002
 
            cell.clear_output(content.stdout, content.stderr, content.other);
1003
 
        };
1004
 
    };
1005
 
 
1006
 
 
1007
 
    Notebook.prototype.handle_status_dead = function () {
1008
 
        var that = this;
1009
 
        this.kernel.stop_channels();
1010
 
        var dialog = $('<div/>');
1011
 
        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.');
1012
 
        $(document).append(dialog);
1013
 
        dialog.dialog({
1014
 
            resizable: false,
1015
 
            modal: true,
1016
 
            title: "Dead kernel",
1017
 
            buttons : {
1018
 
                "Restart": function () {
1019
 
                    that.start_kernel();
1020
 
                    $(this).dialog('close');
1021
 
                },
1022
 
                "Continue running": function () {
1023
 
                    $(this).dialog('close');
1024
 
                }
1025
 
            }
1026
 
        });
1027
 
    };
1028
 
 
1029
 
 
1030
 
    Notebook.prototype.handle_output = function (cell, msg_type, content) {
1031
 
        var json = {};
1032
 
        json.output_type = msg_type;
1033
 
        if (msg_type === "stream") {
1034
 
            json.text = content.data;
1035
 
            json.stream = content.name;
1036
 
        } else if (msg_type === "display_data") {
1037
 
            json = this.convert_mime_types(json, content.data);
1038
 
        } else if (msg_type === "pyout") {
1039
 
            json.prompt_number = content.execution_count;
1040
 
            json = this.convert_mime_types(json, content.data);
1041
 
        } else if (msg_type === "pyerr") {
1042
 
            json.ename = content.ename;
1043
 
            json.evalue = content.evalue;
1044
 
            json.traceback = content.traceback;
1045
 
        };
1046
 
        // append with dynamic=true
1047
 
        cell.append_output(json, true);
1048
 
        this.dirty = true;
1049
 
    };
1050
 
 
1051
 
 
1052
 
    Notebook.prototype.convert_mime_types = function (json, data) {
1053
 
        if (data['text/plain'] !== undefined) {
1054
 
            json.text = data['text/plain'];
1055
 
        };
1056
 
        if (data['text/html'] !== undefined) {
1057
 
            json.html = data['text/html'];
1058
 
        };
1059
 
        if (data['image/svg+xml'] !== undefined) {
1060
 
            json.svg = data['image/svg+xml'];
1061
 
        };
1062
 
        if (data['image/png'] !== undefined) {
1063
 
            json.png = data['image/png'];
1064
 
        };
1065
 
        if (data['image/jpeg'] !== undefined) {
1066
 
            json.jpeg = data['image/jpeg'];
1067
 
        };
1068
 
        if (data['text/latex'] !== undefined) {
1069
 
            json.latex = data['text/latex'];
1070
 
        };
1071
 
        if (data['application/json'] !== undefined) {
1072
 
            json.json = data['application/json'];
1073
 
        };
1074
 
        if (data['application/javascript'] !== undefined) {
1075
 
            json.javascript = data['application/javascript'];
1076
 
        }
1077
 
        return json;    
1078
 
    };
1079
 
 
1080
 
 
1081
 
    Notebook.prototype.execute_selected_cell = function (options) {
1082
 
        // add_new: should a new cell be added if we are at the end of the nb
1083
 
        // terminal: execute in terminal mode, which stays in the current cell
1084
 
        default_options = {terminal: false, add_new: true};
1085
 
        $.extend(default_options, options);
1086
 
        var that = this;
1087
 
        var cell = that.get_selected_cell();
1088
 
        var cell_index = that.find_cell_index(cell);
1089
 
        if (cell instanceof IPython.CodeCell) {
1090
 
            cell.clear_output(true, true, true);
1091
 
            cell.set_input_prompt('*');
1092
 
            cell.element.addClass("running");
1093
 
            var code = cell.get_text();
1094
 
            var msg_id = that.kernel.execute(cell.get_text());
1095
 
            that.msg_cell_map[msg_id] = cell.cell_id;
1096
 
        } else if (cell instanceof IPython.HTMLCell) {
1097
 
            cell.render();
1098
 
        }
1099
 
        if (default_options.terminal) {
1100
 
            cell.select_all();
1101
 
        } else {
1102
 
            if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
1103
 
                that.insert_cell_below('code');
1104
 
                // If we are adding a new cell at the end, scroll down to show it.
1105
 
                that.scroll_to_bottom();
1106
 
            } else {
1107
 
                that.select(cell_index+1);
1108
 
            };
1109
 
        };
1110
 
        this.dirty = true;
1111
 
    };
1112
 
 
1113
 
 
1114
 
    Notebook.prototype.execute_all_cells = function () {
1115
 
        var ncells = this.ncells();
1116
 
        for (var i=0; i<ncells; i++) {
1117
 
            this.select(i);
1118
 
            this.execute_selected_cell({add_new:false});
1119
 
        };
1120
 
        this.scroll_to_bottom();
1121
 
    };
1122
 
 
1123
 
 
1124
 
    Notebook.prototype.request_tool_tip = function (cell,func) {
1125
 
        // Feel free to shorten this logic if you are better
1126
 
        // than me in regEx
1127
 
        // basicaly you shoul be able to get xxx.xxx.xxx from 
1128
 
        // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2, 
1129
 
        // remove everything between matchin bracket (need to iterate)
1130
 
        matchBracket = /\([^\(\)]+\)/g;
1131
 
        oldfunc = func;
1132
 
        func = func.replace(matchBracket,"");
1133
 
        while( oldfunc != func )
1134
 
        {
1135
 
        oldfunc = func;
1136
 
        func = func.replace(matchBracket,"");
1137
 
        }
1138
 
        // remove everythin after last open bracket
1139
 
        endBracket = /\([^\(]*$/g;
1140
 
        func = func.replace(endBracket,"");
1141
 
        var re = /[a-zA-Z._]+$/g;
1142
 
        var msg_id = this.kernel.object_info_request(re.exec(func));
1143
 
        if(typeof(msg_id)!='undefined'){
1144
 
            this.msg_cell_map[msg_id] = cell.cell_id;
1145
 
            }
1146
 
    };
1147
 
 
1148
 
    Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
1149
 
        var msg_id = this.kernel.complete(line, cursor_pos);
1150
 
        this.msg_cell_map[msg_id] = cell.cell_id;
1151
 
    };
1152
 
 
1153
 
 
1154
 
    // Persistance and loading
1155
 
 
1156
 
    Notebook.prototype.get_notebook_id = function () {
1157
 
        return this.notebook_id;
1158
 
    };
1159
 
 
1160
 
 
1161
 
    Notebook.prototype.get_notebook_name = function () {
1162
 
        return this.notebook_name;
1163
 
    };
1164
 
 
1165
 
 
1166
 
    Notebook.prototype.set_notebook_name = function (name) {
1167
 
        this.notebook_name = name;
1168
 
    };
1169
 
 
1170
 
 
1171
 
    Notebook.prototype.test_notebook_name = function (nbname) {
1172
 
        nbname = nbname || '';
1173
 
        if (this.notebook_name_blacklist_re.test(nbname) == false && nbname.length>0) {
1174
 
            return true;
1175
 
        } else {
1176
 
            return false;
1177
 
        };
1178
 
    };
1179
 
 
1180
 
 
1181
 
    Notebook.prototype.fromJSON = function (data) {
1182
 
        var ncells = this.ncells();
1183
 
        var i;
1184
 
        for (i=0; i<ncells; i++) {
1185
 
            // Always delete cell 0 as they get renumbered as they are deleted.
1186
 
            this.delete_cell(0);
1187
 
        };
1188
 
        // Save the metadata and name.
1189
 
        this.metadata = data.metadata;
1190
 
        this.notebook_name = data.metadata.name;
1191
 
        // Only handle 1 worksheet for now.
1192
 
        var worksheet = data.worksheets[0];
1193
 
        if (worksheet !== undefined) {
1194
 
            var new_cells = worksheet.cells;
1195
 
            ncells = new_cells.length;
1196
 
            var cell_data = null;
1197
 
            var new_cell = null;
1198
 
            for (i=0; i<ncells; i++) {
1199
 
                cell_data = new_cells[i];
1200
 
                new_cell = this.insert_cell_below(cell_data.cell_type);
1201
 
                new_cell.fromJSON(cell_data);
1202
 
            };
1203
 
        };
1204
 
    };
1205
 
 
1206
 
 
1207
 
    Notebook.prototype.toJSON = function () {
1208
 
        var cells = this.get_cells();
1209
 
        var ncells = cells.length;
1210
 
        cell_array = new Array(ncells);
1211
 
        for (var i=0; i<ncells; i++) {
1212
 
            cell_array[i] = cells[i].toJSON();
1213
 
        };
1214
 
        data = {
1215
 
            // Only handle 1 worksheet for now.
1216
 
            worksheets : [{cells:cell_array}],
1217
 
            metadata : this.metadata
1218
 
        };
1219
 
        return data;
1220
 
    };
1221
 
 
1222
 
    Notebook.prototype.save_notebook = function () {
1223
 
        // We may want to move the name/id/nbformat logic inside toJSON?
1224
 
        var data = this.toJSON();
1225
 
        data.metadata.name = this.notebook_name;
1226
 
        data.nbformat = this.nbformat;
1227
 
        // We do the call with settings so we can set cache to false.
1228
 
        var settings = {
1229
 
            processData : false,
1230
 
            cache : false,
1231
 
            type : "PUT",
1232
 
            data : JSON.stringify(data),
1233
 
            headers : {'Content-Type': 'application/json'},
1234
 
            success : $.proxy(this.save_notebook_success,this),
1235
 
            error : $.proxy(this.save_notebook_error,this)
1236
 
        };
1237
 
        $([IPython.events]).trigger('notebook_saving.Notebook');
1238
 
        var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
1239
 
        $.ajax(url, settings);
1240
 
    };
1241
 
 
1242
 
 
1243
 
    Notebook.prototype.save_notebook_success = function (data, status, xhr) {
1244
 
        this.dirty = false;
1245
 
        $([IPython.events]).trigger('notebook_saved.Notebook');
1246
 
    };
1247
 
 
1248
 
 
1249
 
    Notebook.prototype.save_notebook_error = function (xhr, status, error_msg) {
1250
 
        $([IPython.events]).trigger('notebook_save_failed.Notebook');
1251
 
    };
1252
 
 
1253
 
 
1254
 
    Notebook.prototype.load_notebook = function (notebook_id) {
1255
 
        var that = this;
1256
 
        this.notebook_id = notebook_id;
1257
 
        // We do the call with settings so we can set cache to false.
1258
 
        var settings = {
1259
 
            processData : false,
1260
 
            cache : false,
1261
 
            type : "GET",
1262
 
            dataType : "json",
1263
 
            success : $.proxy(this.load_notebook_success,this),
1264
 
            error : $.proxy(this.load_notebook_error,this),
1265
 
        };
1266
 
        $([IPython.events]).trigger('notebook_loading.Notebook');
1267
 
        var url = $('body').data('baseProjectUrl') + 'notebooks/' + this.notebook_id;
1268
 
        $.ajax(url, settings);
1269
 
    };
1270
 
 
1271
 
 
1272
 
    Notebook.prototype.load_notebook_success = function (data, status, xhr) {
1273
 
        this.fromJSON(data);
1274
 
        if (this.ncells() === 0) {
1275
 
            this.insert_cell_below('code');
1276
 
        };
1277
 
        this.dirty = false;
1278
 
        if (! this.read_only) {
1279
 
            this.start_kernel();
1280
 
        }
1281
 
        this.select(0);
1282
 
        this.scroll_to_top();
1283
 
        if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
1284
 
            msg = "This notebook has been converted from an older " +
1285
 
            "notebook format (v"+data.orig_nbformat+") to the current notebook " +
1286
 
            "format (v"+data.nbformat+"). The next time you save this notebook, the " +
1287
 
            "newer notebook format will be used and older verions of IPython " +
1288
 
            "may not be able to read it. To keep the older version, close the " +
1289
 
            "notebook without saving it.";
1290
 
            var dialog = $('<div/>');
1291
 
            dialog.html(msg);
1292
 
            this.element.append(dialog);
1293
 
            dialog.dialog({
1294
 
                resizable: false,
1295
 
                modal: true,
1296
 
                title: "Notebook converted",
1297
 
                closeText: "",
1298
 
                close: function(event, ui) {$(this).dialog('destroy').remove();},
1299
 
                buttons : {
1300
 
                    "OK": function () {
1301
 
                        $(this).dialog('close');
1302
 
                    }
1303
 
                },
1304
 
                width: 400
1305
 
            });
1306
 
        }
1307
 
        $([IPython.events]).trigger('notebook_loaded.Notebook');
1308
 
    };
1309
 
 
1310
 
 
1311
 
    Notebook.prototype.load_notebook_error = function (xhr, textStatus, errorThrow) {
1312
 
        if (xhr.status === 500) {
1313
 
            msg = "An error occurred while loading this notebook. Most likely " +
1314
 
            "this notebook is in a newer format than is supported by this " +
1315
 
            "version of IPython. This version can load notebook formats " +
1316
 
            "v"+this.nbformat+" or earlier.";
1317
 
            var dialog = $('<div/>');
1318
 
            dialog.html(msg);
1319
 
            this.element.append(dialog);
1320
 
            dialog.dialog({
1321
 
                resizable: false,
1322
 
                modal: true,
1323
 
                title: "Error loading notebook",
1324
 
                closeText: "",
1325
 
                close: function(event, ui) {$(this).dialog('destroy').remove();},
1326
 
                buttons : {
1327
 
                    "OK": function () {
1328
 
                        $(this).dialog('close');
1329
 
                    }
1330
 
                },
1331
 
                width: 400
1332
 
            });
1333
 
        }
1334
 
    }
1335
 
    
1336
 
    IPython.Notebook = Notebook;
1337
 
 
1338
 
 
1339
 
    return IPython;
1340
 
 
1341
 
}(IPython));
1342