##// END OF EJS Templates
Change button labels in restart dialog to action words.
Fernando Perez -
Show More
@@ -1,972 +1,972 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Notebook
9 // Notebook
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16 var Notebook = function (selector) {
16 var Notebook = function (selector) {
17 this.element = $(selector);
17 this.element = $(selector);
18 this.element.scroll();
18 this.element.scroll();
19 this.element.data("notebook", this);
19 this.element.data("notebook", this);
20 this.next_prompt_number = 1;
20 this.next_prompt_number = 1;
21 this.kernel = null;
21 this.kernel = null;
22 this.dirty = false;
22 this.dirty = false;
23 this.msg_cell_map = {};
23 this.msg_cell_map = {};
24 this.metadata = {};
24 this.metadata = {};
25 this.control_key_active = false;
25 this.control_key_active = false;
26 this.style();
26 this.style();
27 this.create_elements();
27 this.create_elements();
28 this.bind_events();
28 this.bind_events();
29 };
29 };
30
30
31
31
32 Notebook.prototype.style = function () {
32 Notebook.prototype.style = function () {
33 $('div#notebook').addClass('border-box-sizing');
33 $('div#notebook').addClass('border-box-sizing');
34 };
34 };
35
35
36
36
37 Notebook.prototype.create_elements = function () {
37 Notebook.prototype.create_elements = function () {
38 // We add this end_space div to the end of the notebook div to:
38 // We add this end_space div to the end of the notebook div to:
39 // i) provide a margin between the last cell and the end of the notebook
39 // i) provide a margin between the last cell and the end of the notebook
40 // ii) to prevent the div from scrolling up when the last cell is being
40 // ii) to prevent the div from scrolling up when the last cell is being
41 // edited, but is too low on the page, which browsers will do automatically.
41 // edited, but is too low on the page, which browsers will do automatically.
42 var that = this;
42 var that = this;
43 var end_space = $('<div class="end_space"></div>').height(150);
43 var end_space = $('<div class="end_space"></div>').height(150);
44 end_space.dblclick(function (e) {
44 end_space.dblclick(function (e) {
45 var ncells = that.ncells();
45 var ncells = that.ncells();
46 that.insert_code_cell_below(ncells-1);
46 that.insert_code_cell_below(ncells-1);
47 });
47 });
48 this.element.append(end_space);
48 this.element.append(end_space);
49 $('div#notebook').addClass('border-box-sizing');
49 $('div#notebook').addClass('border-box-sizing');
50 };
50 };
51
51
52
52
53 Notebook.prototype.bind_events = function () {
53 Notebook.prototype.bind_events = function () {
54 var that = this;
54 var that = this;
55 $(document).keydown(function (event) {
55 $(document).keydown(function (event) {
56 // console.log(event);
56 // console.log(event);
57 if (event.which === 38) {
57 if (event.which === 38) {
58 var cell = that.selected_cell();
58 var cell = that.selected_cell();
59 if (cell.at_top()) {
59 if (cell.at_top()) {
60 event.preventDefault();
60 event.preventDefault();
61 that.select_prev();
61 that.select_prev();
62 };
62 };
63 } else if (event.which === 40) {
63 } else if (event.which === 40) {
64 var cell = that.selected_cell();
64 var cell = that.selected_cell();
65 if (cell.at_bottom()) {
65 if (cell.at_bottom()) {
66 event.preventDefault();
66 event.preventDefault();
67 that.select_next();
67 that.select_next();
68 };
68 };
69 } else if (event.which === 13 && event.shiftKey) {
69 } else if (event.which === 13 && event.shiftKey) {
70 that.execute_selected_cell();
70 that.execute_selected_cell();
71 return false;
71 return false;
72 } else if (event.which === 13 && event.ctrlKey) {
72 } else if (event.which === 13 && event.ctrlKey) {
73 that.execute_selected_cell({terminal:true});
73 that.execute_selected_cell({terminal:true});
74 return false;
74 return false;
75 } else if (event.which === 77 && event.ctrlKey) {
75 } else if (event.which === 77 && event.ctrlKey) {
76 that.control_key_active = true;
76 that.control_key_active = true;
77 return false;
77 return false;
78 } else if (event.which === 68 && that.control_key_active) {
78 } else if (event.which === 68 && that.control_key_active) {
79 // Delete selected cell = d
79 // Delete selected cell = d
80 that.delete_cell();
80 that.delete_cell();
81 that.control_key_active = false;
81 that.control_key_active = false;
82 return false;
82 return false;
83 } else if (event.which === 65 && that.control_key_active) {
83 } else if (event.which === 65 && that.control_key_active) {
84 // Insert code cell above selected = a
84 // Insert code cell above selected = a
85 that.insert_code_cell_above();
85 that.insert_code_cell_above();
86 that.control_key_active = false;
86 that.control_key_active = false;
87 return false;
87 return false;
88 } else if (event.which === 66 && that.control_key_active) {
88 } else if (event.which === 66 && that.control_key_active) {
89 // Insert code cell below selected = b
89 // Insert code cell below selected = b
90 that.insert_code_cell_below();
90 that.insert_code_cell_below();
91 that.control_key_active = false;
91 that.control_key_active = false;
92 return false;
92 return false;
93 } else if (event.which === 67 && that.control_key_active) {
93 } else if (event.which === 67 && that.control_key_active) {
94 // To code = c
94 // To code = c
95 that.to_code();
95 that.to_code();
96 that.control_key_active = false;
96 that.control_key_active = false;
97 return false;
97 return false;
98 } else if (event.which === 77 && that.control_key_active) {
98 } else if (event.which === 77 && that.control_key_active) {
99 // To markdown = m
99 // To markdown = m
100 that.to_markdown();
100 that.to_markdown();
101 that.control_key_active = false;
101 that.control_key_active = false;
102 return false;
102 return false;
103 } else if (event.which === 84 && that.control_key_active) {
103 } else if (event.which === 84 && that.control_key_active) {
104 // Toggle output = t
104 // Toggle output = t
105 that.toggle_output();
105 that.toggle_output();
106 that.control_key_active = false;
106 that.control_key_active = false;
107 return false;
107 return false;
108 } else if (event.which === 83 && that.control_key_active) {
108 } else if (event.which === 83 && that.control_key_active) {
109 // Save notebook = s
109 // Save notebook = s
110 IPython.save_widget.save_notebook();
110 IPython.save_widget.save_notebook();
111 that.control_key_active = false;
111 that.control_key_active = false;
112 return false;
112 return false;
113 } else if (event.which === 74 && that.control_key_active) {
113 } else if (event.which === 74 && that.control_key_active) {
114 // Move cell down = j
114 // Move cell down = j
115 that.move_cell_down();
115 that.move_cell_down();
116 that.control_key_active = false;
116 that.control_key_active = false;
117 return false;
117 return false;
118 } else if (event.which === 75 && that.control_key_active) {
118 } else if (event.which === 75 && that.control_key_active) {
119 // Move cell up = k
119 // Move cell up = k
120 that.move_cell_up();
120 that.move_cell_up();
121 that.control_key_active = false;
121 that.control_key_active = false;
122 return false;
122 return false;
123 } else if (event.which === 80 && that.control_key_active) {
123 } else if (event.which === 80 && that.control_key_active) {
124 // Select previous = p
124 // Select previous = p
125 that.select_prev();
125 that.select_prev();
126 that.control_key_active = false;
126 that.control_key_active = false;
127 return false;
127 return false;
128 } else if (event.which === 78 && that.control_key_active) {
128 } else if (event.which === 78 && that.control_key_active) {
129 // Select next = n
129 // Select next = n
130 that.select_next();
130 that.select_next();
131 that.control_key_active = false;
131 that.control_key_active = false;
132 return false;
132 return false;
133 } else if (event.which === 72 && that.control_key_active) {
133 } else if (event.which === 72 && that.control_key_active) {
134 // Show keyboard shortcuts = h
134 // Show keyboard shortcuts = h
135 that.show_keyboard_shortcuts();
135 that.show_keyboard_shortcuts();
136 that.control_key_active = false;
136 that.control_key_active = false;
137 return false;
137 return false;
138 } else if (event.which === 73 && that.control_key_active) {
138 } else if (event.which === 73 && that.control_key_active) {
139 // Interrupt kernel = i
139 // Interrupt kernel = i
140 IPython.notebook.kernel.interrupt();
140 IPython.notebook.kernel.interrupt();
141 that.control_key_active = false;
141 that.control_key_active = false;
142 return false;
142 return false;
143 } else if (event.which === 76 && that.control_key_active) {
143 } else if (event.which === 76 && that.control_key_active) {
144 // Toggle line numbers = l
144 // Toggle line numbers = l
145 that.cell_toggle_line_numbers();
145 that.cell_toggle_line_numbers();
146 that.control_key_active = false;
146 that.control_key_active = false;
147 return false;
147 return false;
148 } else if (event.which === 190 && that.control_key_active) {
148 } else if (event.which === 190 && that.control_key_active) {
149 // Restart kernel = . # matches qt console
149 // Restart kernel = . # matches qt console
150 IPython.notebook.restart_kernel();
150 IPython.notebook.restart_kernel();
151 that.control_key_active = false;
151 that.control_key_active = false;
152 return false;
152 return false;
153 } else if (that.control_key_active) {
153 } else if (that.control_key_active) {
154 that.control_key_active = false;
154 that.control_key_active = false;
155 return true;
155 return true;
156 };
156 };
157 });
157 });
158
158
159 this.element.bind('collapse_pager', function () {
159 this.element.bind('collapse_pager', function () {
160 var app_height = $('div#main_app').height(); // content height
160 var app_height = $('div#main_app').height(); // content height
161 var splitter_height = $('div#pager_splitter').outerHeight(true);
161 var splitter_height = $('div#pager_splitter').outerHeight(true);
162 var new_height = app_height - splitter_height;
162 var new_height = app_height - splitter_height;
163 that.element.animate({height : new_height + 'px'}, 'fast');
163 that.element.animate({height : new_height + 'px'}, 'fast');
164 });
164 });
165
165
166 this.element.bind('expand_pager', function () {
166 this.element.bind('expand_pager', function () {
167 var app_height = $('div#main_app').height(); // content height
167 var app_height = $('div#main_app').height(); // content height
168 var splitter_height = $('div#pager_splitter').outerHeight(true);
168 var splitter_height = $('div#pager_splitter').outerHeight(true);
169 var pager_height = $('div#pager').outerHeight(true);
169 var pager_height = $('div#pager').outerHeight(true);
170 var new_height = app_height - pager_height - splitter_height;
170 var new_height = app_height - pager_height - splitter_height;
171 that.element.animate({height : new_height + 'px'}, 'fast');
171 that.element.animate({height : new_height + 'px'}, 'fast');
172 });
172 });
173
173
174 this.element.bind('collapse_left_panel', function () {
174 this.element.bind('collapse_left_panel', function () {
175 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
175 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
176 var new_margin = splitter_width;
176 var new_margin = splitter_width;
177 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
177 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
178 });
178 });
179
179
180 this.element.bind('expand_left_panel', function () {
180 this.element.bind('expand_left_panel', function () {
181 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
181 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
182 var left_panel_width = IPython.left_panel.width;
182 var left_panel_width = IPython.left_panel.width;
183 var new_margin = splitter_width + left_panel_width;
183 var new_margin = splitter_width + left_panel_width;
184 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
184 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
185 });
185 });
186
186
187 $(window).bind('beforeunload', function () {
187 $(window).bind('beforeunload', function () {
188 var kill_kernel = $('#kill_kernel').prop('checked');
188 var kill_kernel = $('#kill_kernel').prop('checked');
189 if (kill_kernel) {
189 if (kill_kernel) {
190 that.kernel.kill();
190 that.kernel.kill();
191 }
191 }
192 if (that.dirty) {
192 if (that.dirty) {
193 return "You have unsaved changes that will be lost if you leave this page.";
193 return "You have unsaved changes that will be lost if you leave this page.";
194 };
194 };
195 });
195 });
196 };
196 };
197
197
198
198
199 Notebook.prototype.show_keyboard_shortcuts = function () {
199 Notebook.prototype.show_keyboard_shortcuts = function () {
200 var dialog = $('<div/>');
200 var dialog = $('<div/>');
201 var shortcuts = [
201 var shortcuts = [
202 {key: 'Shift-Enter', help: 'run cell'},
202 {key: 'Shift-Enter', help: 'run cell'},
203 {key: 'Ctrl-Enter', help: 'run cell in-place'},
203 {key: 'Ctrl-Enter', help: 'run cell in-place'},
204 {key: 'Ctrl-m d', help: 'delete cell'},
204 {key: 'Ctrl-m d', help: 'delete cell'},
205 {key: 'Ctrl-m a', help: 'insert cell above'},
205 {key: 'Ctrl-m a', help: 'insert cell above'},
206 {key: 'Ctrl-m b', help: 'insert cell below'},
206 {key: 'Ctrl-m b', help: 'insert cell below'},
207 {key: 'Ctrl-m t', help: 'toggle output'},
207 {key: 'Ctrl-m t', help: 'toggle output'},
208 {key: 'Ctrl-m l', help: 'toggle line numbers'},
208 {key: 'Ctrl-m l', help: 'toggle line numbers'},
209 {key: 'Ctrl-m s', help: 'save notebook'},
209 {key: 'Ctrl-m s', help: 'save notebook'},
210 {key: 'Ctrl-m j', help: 'move cell down'},
210 {key: 'Ctrl-m j', help: 'move cell down'},
211 {key: 'Ctrl-m k', help: 'move cell up'},
211 {key: 'Ctrl-m k', help: 'move cell up'},
212 {key: 'Ctrl-m c', help: 'code cell'},
212 {key: 'Ctrl-m c', help: 'code cell'},
213 {key: 'Ctrl-m m', help: 'markdown cell'},
213 {key: 'Ctrl-m m', help: 'markdown cell'},
214 {key: 'Ctrl-m p', help: 'select previous'},
214 {key: 'Ctrl-m p', help: 'select previous'},
215 {key: 'Ctrl-m n', help: 'select next'},
215 {key: 'Ctrl-m n', help: 'select next'},
216 {key: 'Ctrl-m i', help: 'interrupt kernel'},
216 {key: 'Ctrl-m i', help: 'interrupt kernel'},
217 {key: 'Ctrl-m .', help: 'restart kernel'},
217 {key: 'Ctrl-m .', help: 'restart kernel'},
218 {key: 'Ctrl-m h', help: 'show keyboard shortcuts'}
218 {key: 'Ctrl-m h', help: 'show keyboard shortcuts'}
219 ];
219 ];
220 for (var i=0; i<shortcuts.length; i++) {
220 for (var i=0; i<shortcuts.length; i++) {
221 dialog.append($('<div>').
221 dialog.append($('<div>').
222 append($('<span/>').addClass('shortcut_key').html(shortcuts[i].key)).
222 append($('<span/>').addClass('shortcut_key').html(shortcuts[i].key)).
223 append($('<span/>').addClass('shortcut_descr').html(' : ' + shortcuts[i].help))
223 append($('<span/>').addClass('shortcut_descr').html(' : ' + shortcuts[i].help))
224 );
224 );
225 };
225 };
226 dialog.dialog({title: 'Keyboard shortcuts'});
226 dialog.dialog({title: 'Keyboard shortcuts'});
227 };
227 };
228
228
229
229
230 Notebook.prototype.scroll_to_bottom = function () {
230 Notebook.prototype.scroll_to_bottom = function () {
231 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
231 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
232 };
232 };
233
233
234
234
235 Notebook.prototype.scroll_to_top = function () {
235 Notebook.prototype.scroll_to_top = function () {
236 this.element.animate({scrollTop:0}, 0);
236 this.element.animate({scrollTop:0}, 0);
237 };
237 };
238
238
239
239
240 // Cell indexing, retrieval, etc.
240 // Cell indexing, retrieval, etc.
241
241
242
242
243 Notebook.prototype.cell_elements = function () {
243 Notebook.prototype.cell_elements = function () {
244 return this.element.children("div.cell");
244 return this.element.children("div.cell");
245 }
245 }
246
246
247
247
248 Notebook.prototype.ncells = function (cell) {
248 Notebook.prototype.ncells = function (cell) {
249 return this.cell_elements().length;
249 return this.cell_elements().length;
250 }
250 }
251
251
252
252
253 // TODO: we are often calling cells as cells()[i], which we should optimize
253 // TODO: we are often calling cells as cells()[i], which we should optimize
254 // to cells(i) or a new method.
254 // to cells(i) or a new method.
255 Notebook.prototype.cells = function () {
255 Notebook.prototype.cells = function () {
256 return this.cell_elements().toArray().map(function (e) {
256 return this.cell_elements().toArray().map(function (e) {
257 return $(e).data("cell");
257 return $(e).data("cell");
258 });
258 });
259 }
259 }
260
260
261
261
262 Notebook.prototype.find_cell_index = function (cell) {
262 Notebook.prototype.find_cell_index = function (cell) {
263 var result = null;
263 var result = null;
264 this.cell_elements().filter(function (index) {
264 this.cell_elements().filter(function (index) {
265 if ($(this).data("cell") === cell) {
265 if ($(this).data("cell") === cell) {
266 result = index;
266 result = index;
267 };
267 };
268 });
268 });
269 return result;
269 return result;
270 };
270 };
271
271
272
272
273 Notebook.prototype.index_or_selected = function (index) {
273 Notebook.prototype.index_or_selected = function (index) {
274 return index || this.selected_index() || 0;
274 return index || this.selected_index() || 0;
275 }
275 }
276
276
277
277
278 Notebook.prototype.select = function (index) {
278 Notebook.prototype.select = function (index) {
279 if (index !== undefined && index >= 0 && index < this.ncells()) {
279 if (index !== undefined && index >= 0 && index < this.ncells()) {
280 if (this.selected_index() !== null) {
280 if (this.selected_index() !== null) {
281 this.selected_cell().unselect();
281 this.selected_cell().unselect();
282 };
282 };
283 this.cells()[index].select();
283 this.cells()[index].select();
284 };
284 };
285 return this;
285 return this;
286 };
286 };
287
287
288
288
289 Notebook.prototype.select_next = function () {
289 Notebook.prototype.select_next = function () {
290 var index = this.selected_index();
290 var index = this.selected_index();
291 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
291 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
292 this.select(index+1);
292 this.select(index+1);
293 };
293 };
294 return this;
294 return this;
295 };
295 };
296
296
297
297
298 Notebook.prototype.select_prev = function () {
298 Notebook.prototype.select_prev = function () {
299 var index = this.selected_index();
299 var index = this.selected_index();
300 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
300 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
301 this.select(index-1);
301 this.select(index-1);
302 };
302 };
303 return this;
303 return this;
304 };
304 };
305
305
306
306
307 Notebook.prototype.selected_index = function () {
307 Notebook.prototype.selected_index = function () {
308 var result = null;
308 var result = null;
309 this.cell_elements().filter(function (index) {
309 this.cell_elements().filter(function (index) {
310 if ($(this).data("cell").selected === true) {
310 if ($(this).data("cell").selected === true) {
311 result = index;
311 result = index;
312 };
312 };
313 });
313 });
314 return result;
314 return result;
315 };
315 };
316
316
317
317
318 Notebook.prototype.cell_for_msg = function (msg_id) {
318 Notebook.prototype.cell_for_msg = function (msg_id) {
319 var cell_id = this.msg_cell_map[msg_id];
319 var cell_id = this.msg_cell_map[msg_id];
320 var result = null;
320 var result = null;
321 this.cell_elements().filter(function (index) {
321 this.cell_elements().filter(function (index) {
322 cell = $(this).data("cell");
322 cell = $(this).data("cell");
323 if (cell.cell_id === cell_id) {
323 if (cell.cell_id === cell_id) {
324 result = cell;
324 result = cell;
325 };
325 };
326 });
326 });
327 return result;
327 return result;
328 };
328 };
329
329
330
330
331 Notebook.prototype.selected_cell = function () {
331 Notebook.prototype.selected_cell = function () {
332 return this.cell_elements().eq(this.selected_index()).data("cell");
332 return this.cell_elements().eq(this.selected_index()).data("cell");
333 }
333 }
334
334
335
335
336 // Cell insertion, deletion and moving.
336 // Cell insertion, deletion and moving.
337
337
338
338
339 Notebook.prototype.delete_cell = function (index) {
339 Notebook.prototype.delete_cell = function (index) {
340 var i = index || this.selected_index();
340 var i = index || this.selected_index();
341 if (i !== null && i >= 0 && i < this.ncells()) {
341 if (i !== null && i >= 0 && i < this.ncells()) {
342 this.cell_elements().eq(i).remove();
342 this.cell_elements().eq(i).remove();
343 if (i === (this.ncells())) {
343 if (i === (this.ncells())) {
344 this.select(i-1);
344 this.select(i-1);
345 } else {
345 } else {
346 this.select(i);
346 this.select(i);
347 };
347 };
348 };
348 };
349 this.dirty = true;
349 this.dirty = true;
350 return this;
350 return this;
351 };
351 };
352
352
353
353
354 Notebook.prototype.append_cell = function (cell) {
354 Notebook.prototype.append_cell = function (cell) {
355 this.element.find('div.end_space').before(cell.element);
355 this.element.find('div.end_space').before(cell.element);
356 this.dirty = true;
356 this.dirty = true;
357 return this;
357 return this;
358 };
358 };
359
359
360
360
361 Notebook.prototype.insert_cell_below = function (cell, index) {
361 Notebook.prototype.insert_cell_below = function (cell, index) {
362 var ncells = this.ncells();
362 var ncells = this.ncells();
363 if (ncells === 0) {
363 if (ncells === 0) {
364 this.append_cell(cell);
364 this.append_cell(cell);
365 return this;
365 return this;
366 };
366 };
367 if (index >= 0 && index < ncells) {
367 if (index >= 0 && index < ncells) {
368 this.cell_elements().eq(index).after(cell.element);
368 this.cell_elements().eq(index).after(cell.element);
369 };
369 };
370 this.dirty = true;
370 this.dirty = true;
371 return this
371 return this
372 };
372 };
373
373
374
374
375 Notebook.prototype.insert_cell_above = function (cell, index) {
375 Notebook.prototype.insert_cell_above = function (cell, index) {
376 var ncells = this.ncells();
376 var ncells = this.ncells();
377 if (ncells === 0) {
377 if (ncells === 0) {
378 this.append_cell(cell);
378 this.append_cell(cell);
379 return this;
379 return this;
380 };
380 };
381 if (index >= 0 && index < ncells) {
381 if (index >= 0 && index < ncells) {
382 this.cell_elements().eq(index).before(cell.element);
382 this.cell_elements().eq(index).before(cell.element);
383 };
383 };
384 this.dirty = true;
384 this.dirty = true;
385 return this;
385 return this;
386 };
386 };
387
387
388
388
389 Notebook.prototype.move_cell_up = function (index) {
389 Notebook.prototype.move_cell_up = function (index) {
390 var i = index || this.selected_index();
390 var i = index || this.selected_index();
391 if (i !== null && i < this.ncells() && i > 0) {
391 if (i !== null && i < this.ncells() && i > 0) {
392 var pivot = this.cell_elements().eq(i-1);
392 var pivot = this.cell_elements().eq(i-1);
393 var tomove = this.cell_elements().eq(i);
393 var tomove = this.cell_elements().eq(i);
394 if (pivot !== null && tomove !== null) {
394 if (pivot !== null && tomove !== null) {
395 tomove.detach();
395 tomove.detach();
396 pivot.before(tomove);
396 pivot.before(tomove);
397 this.select(i-1);
397 this.select(i-1);
398 };
398 };
399 };
399 };
400 this.dirty = true;
400 this.dirty = true;
401 return this;
401 return this;
402 }
402 }
403
403
404
404
405 Notebook.prototype.move_cell_down = function (index) {
405 Notebook.prototype.move_cell_down = function (index) {
406 var i = index || this.selected_index();
406 var i = index || this.selected_index();
407 if (i !== null && i < (this.ncells()-1) && i >= 0) {
407 if (i !== null && i < (this.ncells()-1) && i >= 0) {
408 var pivot = this.cell_elements().eq(i+1)
408 var pivot = this.cell_elements().eq(i+1)
409 var tomove = this.cell_elements().eq(i)
409 var tomove = this.cell_elements().eq(i)
410 if (pivot !== null && tomove !== null) {
410 if (pivot !== null && tomove !== null) {
411 tomove.detach();
411 tomove.detach();
412 pivot.after(tomove);
412 pivot.after(tomove);
413 this.select(i+1);
413 this.select(i+1);
414 };
414 };
415 };
415 };
416 this.dirty = true;
416 this.dirty = true;
417 return this;
417 return this;
418 }
418 }
419
419
420
420
421 Notebook.prototype.sort_cells = function () {
421 Notebook.prototype.sort_cells = function () {
422 var ncells = this.ncells();
422 var ncells = this.ncells();
423 var sindex = this.selected_index();
423 var sindex = this.selected_index();
424 var swapped;
424 var swapped;
425 do {
425 do {
426 swapped = false
426 swapped = false
427 for (var i=1; i<ncells; i++) {
427 for (var i=1; i<ncells; i++) {
428 current = this.cell_elements().eq(i).data("cell");
428 current = this.cell_elements().eq(i).data("cell");
429 previous = this.cell_elements().eq(i-1).data("cell");
429 previous = this.cell_elements().eq(i-1).data("cell");
430 if (previous.input_prompt_number > current.input_prompt_number) {
430 if (previous.input_prompt_number > current.input_prompt_number) {
431 this.move_cell_up(i);
431 this.move_cell_up(i);
432 swapped = true;
432 swapped = true;
433 };
433 };
434 };
434 };
435 } while (swapped);
435 } while (swapped);
436 this.select(sindex);
436 this.select(sindex);
437 return this;
437 return this;
438 };
438 };
439
439
440
440
441 Notebook.prototype.insert_code_cell_above = function (index) {
441 Notebook.prototype.insert_code_cell_above = function (index) {
442 // TODO: Bounds check for i
442 // TODO: Bounds check for i
443 var i = this.index_or_selected(index);
443 var i = this.index_or_selected(index);
444 var cell = new IPython.CodeCell(this);
444 var cell = new IPython.CodeCell(this);
445 cell.set_input_prompt();
445 cell.set_input_prompt();
446 this.insert_cell_above(cell, i);
446 this.insert_cell_above(cell, i);
447 this.select(this.find_cell_index(cell));
447 this.select(this.find_cell_index(cell));
448 return cell;
448 return cell;
449 }
449 }
450
450
451
451
452 Notebook.prototype.insert_code_cell_below = function (index) {
452 Notebook.prototype.insert_code_cell_below = function (index) {
453 // TODO: Bounds check for i
453 // TODO: Bounds check for i
454 var i = this.index_or_selected(index);
454 var i = this.index_or_selected(index);
455 var cell = new IPython.CodeCell(this);
455 var cell = new IPython.CodeCell(this);
456 cell.set_input_prompt();
456 cell.set_input_prompt();
457 this.insert_cell_below(cell, i);
457 this.insert_cell_below(cell, i);
458 this.select(this.find_cell_index(cell));
458 this.select(this.find_cell_index(cell));
459 return cell;
459 return cell;
460 }
460 }
461
461
462
462
463 Notebook.prototype.insert_html_cell_above = function (index) {
463 Notebook.prototype.insert_html_cell_above = function (index) {
464 // TODO: Bounds check for i
464 // TODO: Bounds check for i
465 var i = this.index_or_selected(index);
465 var i = this.index_or_selected(index);
466 var cell = new IPython.HTMLCell(this);
466 var cell = new IPython.HTMLCell(this);
467 cell.config_mathjax();
467 cell.config_mathjax();
468 this.insert_cell_above(cell, i);
468 this.insert_cell_above(cell, i);
469 this.select(this.find_cell_index(cell));
469 this.select(this.find_cell_index(cell));
470 return cell;
470 return cell;
471 }
471 }
472
472
473
473
474 Notebook.prototype.insert_html_cell_below = function (index) {
474 Notebook.prototype.insert_html_cell_below = function (index) {
475 // TODO: Bounds check for i
475 // TODO: Bounds check for i
476 var i = this.index_or_selected(index);
476 var i = this.index_or_selected(index);
477 var cell = new IPython.HTMLCell(this);
477 var cell = new IPython.HTMLCell(this);
478 cell.config_mathjax();
478 cell.config_mathjax();
479 this.insert_cell_below(cell, i);
479 this.insert_cell_below(cell, i);
480 this.select(this.find_cell_index(cell));
480 this.select(this.find_cell_index(cell));
481 return cell;
481 return cell;
482 }
482 }
483
483
484
484
485 Notebook.prototype.insert_markdown_cell_above = function (index) {
485 Notebook.prototype.insert_markdown_cell_above = function (index) {
486 // TODO: Bounds check for i
486 // TODO: Bounds check for i
487 var i = this.index_or_selected(index);
487 var i = this.index_or_selected(index);
488 var cell = new IPython.MarkdownCell(this);
488 var cell = new IPython.MarkdownCell(this);
489 cell.config_mathjax();
489 cell.config_mathjax();
490 this.insert_cell_above(cell, i);
490 this.insert_cell_above(cell, i);
491 this.select(this.find_cell_index(cell));
491 this.select(this.find_cell_index(cell));
492 return cell;
492 return cell;
493 }
493 }
494
494
495
495
496 Notebook.prototype.insert_markdown_cell_below = function (index) {
496 Notebook.prototype.insert_markdown_cell_below = function (index) {
497 // TODO: Bounds check for i
497 // TODO: Bounds check for i
498 var i = this.index_or_selected(index);
498 var i = this.index_or_selected(index);
499 var cell = new IPython.MarkdownCell(this);
499 var cell = new IPython.MarkdownCell(this);
500 cell.config_mathjax();
500 cell.config_mathjax();
501 this.insert_cell_below(cell, i);
501 this.insert_cell_below(cell, i);
502 this.select(this.find_cell_index(cell));
502 this.select(this.find_cell_index(cell));
503 return cell;
503 return cell;
504 }
504 }
505
505
506
506
507 Notebook.prototype.to_code = function (index) {
507 Notebook.prototype.to_code = function (index) {
508 // TODO: Bounds check for i
508 // TODO: Bounds check for i
509 var i = this.index_or_selected(index);
509 var i = this.index_or_selected(index);
510 var source_element = this.cell_elements().eq(i);
510 var source_element = this.cell_elements().eq(i);
511 var source_cell = source_element.data("cell");
511 var source_cell = source_element.data("cell");
512 if (source_cell instanceof IPython.HTMLCell ||
512 if (source_cell instanceof IPython.HTMLCell ||
513 source_cell instanceof IPython.MarkdownCell) {
513 source_cell instanceof IPython.MarkdownCell) {
514 this.insert_code_cell_below(i);
514 this.insert_code_cell_below(i);
515 var target_cell = this.cells()[i+1];
515 var target_cell = this.cells()[i+1];
516 target_cell.set_code(source_cell.get_source());
516 target_cell.set_code(source_cell.get_source());
517 source_element.remove();
517 source_element.remove();
518 target_cell.select();
518 target_cell.select();
519 };
519 };
520 this.dirty = true;
520 this.dirty = true;
521 };
521 };
522
522
523
523
524 Notebook.prototype.to_markdown = function (index) {
524 Notebook.prototype.to_markdown = function (index) {
525 // TODO: Bounds check for i
525 // TODO: Bounds check for i
526 var i = this.index_or_selected(index);
526 var i = this.index_or_selected(index);
527 var source_element = this.cell_elements().eq(i);
527 var source_element = this.cell_elements().eq(i);
528 var source_cell = source_element.data("cell");
528 var source_cell = source_element.data("cell");
529 var target_cell = null;
529 var target_cell = null;
530 if (source_cell instanceof IPython.CodeCell) {
530 if (source_cell instanceof IPython.CodeCell) {
531 this.insert_markdown_cell_below(i);
531 this.insert_markdown_cell_below(i);
532 var target_cell = this.cells()[i+1];
532 var target_cell = this.cells()[i+1];
533 var text = source_cell.get_code();
533 var text = source_cell.get_code();
534 } else if (source_cell instanceof IPython.HTMLCell) {
534 } else if (source_cell instanceof IPython.HTMLCell) {
535 this.insert_markdown_cell_below(i);
535 this.insert_markdown_cell_below(i);
536 var target_cell = this.cells()[i+1];
536 var target_cell = this.cells()[i+1];
537 var text = source_cell.get_source();
537 var text = source_cell.get_source();
538 if (text === source_cell.placeholder) {
538 if (text === source_cell.placeholder) {
539 text = target_cell.placeholder;
539 text = target_cell.placeholder;
540 }
540 }
541 }
541 }
542 if (target_cell !== null) {
542 if (target_cell !== null) {
543 if (text === "") {text = target_cell.placeholder;};
543 if (text === "") {text = target_cell.placeholder;};
544 target_cell.set_source(text);
544 target_cell.set_source(text);
545 source_element.remove();
545 source_element.remove();
546 target_cell.edit();
546 target_cell.edit();
547 }
547 }
548 this.dirty = true;
548 this.dirty = true;
549 };
549 };
550
550
551
551
552 Notebook.prototype.to_html = function (index) {
552 Notebook.prototype.to_html = function (index) {
553 // TODO: Bounds check for i
553 // TODO: Bounds check for i
554 var i = this.index_or_selected(index);
554 var i = this.index_or_selected(index);
555 var source_element = this.cell_elements().eq(i);
555 var source_element = this.cell_elements().eq(i);
556 var source_cell = source_element.data("cell");
556 var source_cell = source_element.data("cell");
557 var target_cell = null;
557 var target_cell = null;
558 if (source_cell instanceof IPython.CodeCell) {
558 if (source_cell instanceof IPython.CodeCell) {
559 this.insert_html_cell_below(i);
559 this.insert_html_cell_below(i);
560 var target_cell = this.cells()[i+1];
560 var target_cell = this.cells()[i+1];
561 var text = source_cell.get_code();
561 var text = source_cell.get_code();
562 } else if (source_cell instanceof IPython.MarkdownCell) {
562 } else if (source_cell instanceof IPython.MarkdownCell) {
563 this.insert_html_cell_below(i);
563 this.insert_html_cell_below(i);
564 var target_cell = this.cells()[i+1];
564 var target_cell = this.cells()[i+1];
565 var text = source_cell.get_source();
565 var text = source_cell.get_source();
566 if (text === source_cell.placeholder) {
566 if (text === source_cell.placeholder) {
567 text = target_cell.placeholder;
567 text = target_cell.placeholder;
568 }
568 }
569 }
569 }
570 if (target_cell !== null) {
570 if (target_cell !== null) {
571 if (text === "") {text = target_cell.placeholder;};
571 if (text === "") {text = target_cell.placeholder;};
572 target_cell.set_source(text);
572 target_cell.set_source(text);
573 source_element.remove();
573 source_element.remove();
574 target_cell.edit();
574 target_cell.edit();
575 }
575 }
576 this.dirty = true;
576 this.dirty = true;
577 };
577 };
578
578
579
579
580 // Cell collapsing and output clearing
580 // Cell collapsing and output clearing
581
581
582 Notebook.prototype.collapse = function (index) {
582 Notebook.prototype.collapse = function (index) {
583 var i = this.index_or_selected(index);
583 var i = this.index_or_selected(index);
584 this.cells()[i].collapse();
584 this.cells()[i].collapse();
585 this.dirty = true;
585 this.dirty = true;
586 };
586 };
587
587
588
588
589 Notebook.prototype.expand = function (index) {
589 Notebook.prototype.expand = function (index) {
590 var i = this.index_or_selected(index);
590 var i = this.index_or_selected(index);
591 this.cells()[i].expand();
591 this.cells()[i].expand();
592 this.dirty = true;
592 this.dirty = true;
593 };
593 };
594
594
595
595
596 Notebook.prototype.toggle_output = function (index) {
596 Notebook.prototype.toggle_output = function (index) {
597 var i = this.index_or_selected(index);
597 var i = this.index_or_selected(index);
598 this.cells()[i].toggle_output();
598 this.cells()[i].toggle_output();
599 this.dirty = true;
599 this.dirty = true;
600 };
600 };
601
601
602
602
603 Notebook.prototype.set_autoindent = function (state) {
603 Notebook.prototype.set_autoindent = function (state) {
604 var cells = this.cells();
604 var cells = this.cells();
605 len = cells.length;
605 len = cells.length;
606 for (var i=0; i<len; i++) {
606 for (var i=0; i<len; i++) {
607 cells[i].set_autoindent(state)
607 cells[i].set_autoindent(state)
608 };
608 };
609 };
609 };
610
610
611
611
612 Notebook.prototype.clear_all_output = function () {
612 Notebook.prototype.clear_all_output = function () {
613 var ncells = this.ncells();
613 var ncells = this.ncells();
614 var cells = this.cells();
614 var cells = this.cells();
615 for (var i=0; i<ncells; i++) {
615 for (var i=0; i<ncells; i++) {
616 if (cells[i] instanceof IPython.CodeCell) {
616 if (cells[i] instanceof IPython.CodeCell) {
617 cells[i].clear_output();
617 cells[i].clear_output();
618 }
618 }
619 };
619 };
620 this.dirty = true;
620 this.dirty = true;
621 };
621 };
622
622
623 // Other cell functions: line numbers, ...
623 // Other cell functions: line numbers, ...
624
624
625 Notebook.prototype.cell_toggle_line_numbers = function() {
625 Notebook.prototype.cell_toggle_line_numbers = function() {
626 this.selected_cell().toggle_line_numbers()
626 this.selected_cell().toggle_line_numbers()
627 };
627 };
628
628
629 // Kernel related things
629 // Kernel related things
630
630
631 Notebook.prototype.start_kernel = function () {
631 Notebook.prototype.start_kernel = function () {
632 this.kernel = new IPython.Kernel();
632 this.kernel = new IPython.Kernel();
633 var notebook_id = IPython.save_widget.get_notebook_id();
633 var notebook_id = IPython.save_widget.get_notebook_id();
634 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
634 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
635 };
635 };
636
636
637
637
638 Notebook.prototype.restart_kernel = function () {
638 Notebook.prototype.restart_kernel = function () {
639 var that = this;
639 var that = this;
640 var notebook_id = IPython.save_widget.get_notebook_id();
640 var notebook_id = IPython.save_widget.get_notebook_id();
641
641
642 var dialog = $('<div/>');
642 var dialog = $('<div/>');
643 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
643 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
644 $(document).append(dialog);
644 $(document).append(dialog);
645 dialog.dialog({
645 dialog.dialog({
646 resizable: false,
646 resizable: false,
647 modal: true,
647 modal: true,
648 title: "Restart kernel or continue running?",
648 title: "Restart kernel or continue running?",
649 buttons : {
649 buttons : {
650 "Restart": function () {
650 "Restart": function () {
651 that.kernel.restart($.proxy(that.kernel_started, that));
651 that.kernel.restart($.proxy(that.kernel_started, that));
652 $(this).dialog('close');
652 $(this).dialog('close');
653 },
653 },
654 "Continue running": function () {
654 "Continue running": function () {
655 $(this).dialog('close');
655 $(this).dialog('close');
656 }
656 }
657 }
657 }
658 });
658 });
659 };
659 };
660
660
661
661
662 Notebook.prototype.kernel_started = function () {
662 Notebook.prototype.kernel_started = function () {
663 console.log("Kernel started: ", this.kernel.kernel_id);
663 console.log("Kernel started: ", this.kernel.kernel_id);
664 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
664 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
665 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
665 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
666 };
666 };
667
667
668
668
669 Notebook.prototype.handle_shell_reply = function (e) {
669 Notebook.prototype.handle_shell_reply = function (e) {
670 reply = $.parseJSON(e.data);
670 reply = $.parseJSON(e.data);
671 var header = reply.header;
671 var header = reply.header;
672 var content = reply.content;
672 var content = reply.content;
673 var msg_type = header.msg_type;
673 var msg_type = header.msg_type;
674 // console.log(reply);
674 // console.log(reply);
675 var cell = this.cell_for_msg(reply.parent_header.msg_id);
675 var cell = this.cell_for_msg(reply.parent_header.msg_id);
676 if (msg_type === "execute_reply") {
676 if (msg_type === "execute_reply") {
677 cell.set_input_prompt(content.execution_count);
677 cell.set_input_prompt(content.execution_count);
678 this.dirty = true;
678 this.dirty = true;
679 } else if (msg_type === "complete_reply") {
679 } else if (msg_type === "complete_reply") {
680 cell.finish_completing(content.matched_text, content.matches);
680 cell.finish_completing(content.matched_text, content.matches);
681 };
681 };
682 var payload = content.payload || [];
682 var payload = content.payload || [];
683 this.handle_payload(cell, payload);
683 this.handle_payload(cell, payload);
684 };
684 };
685
685
686
686
687 Notebook.prototype.handle_payload = function (cell, payload) {
687 Notebook.prototype.handle_payload = function (cell, payload) {
688 var l = payload.length;
688 var l = payload.length;
689 for (var i=0; i<l; i++) {
689 for (var i=0; i<l; i++) {
690 if (payload[i].source === 'IPython.zmq.page.page') {
690 if (payload[i].source === 'IPython.zmq.page.page') {
691 if (payload[i].text.trim() !== '') {
691 if (payload[i].text.trim() !== '') {
692 IPython.pager.clear();
692 IPython.pager.clear();
693 IPython.pager.expand();
693 IPython.pager.expand();
694 IPython.pager.append_text(payload[i].text);
694 IPython.pager.append_text(payload[i].text);
695 }
695 }
696 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
696 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
697 var index = this.find_cell_index(cell);
697 var index = this.find_cell_index(cell);
698 var new_cell = this.insert_code_cell_below(index);
698 var new_cell = this.insert_code_cell_below(index);
699 new_cell.set_code(payload[i].text);
699 new_cell.set_code(payload[i].text);
700 this.dirty = true;
700 this.dirty = true;
701 }
701 }
702 };
702 };
703 };
703 };
704
704
705
705
706 Notebook.prototype.handle_iopub_reply = function (e) {
706 Notebook.prototype.handle_iopub_reply = function (e) {
707 reply = $.parseJSON(e.data);
707 reply = $.parseJSON(e.data);
708 var content = reply.content;
708 var content = reply.content;
709 // console.log(reply);
709 // console.log(reply);
710 var msg_type = reply.header.msg_type;
710 var msg_type = reply.header.msg_type;
711 var cell = this.cell_for_msg(reply.parent_header.msg_id);
711 var cell = this.cell_for_msg(reply.parent_header.msg_id);
712 var output_types = ['stream','display_data','pyout','pyerr'];
712 var output_types = ['stream','display_data','pyout','pyerr'];
713 if (output_types.indexOf(msg_type) >= 0) {
713 if (output_types.indexOf(msg_type) >= 0) {
714 this.handle_output(cell, msg_type, content);
714 this.handle_output(cell, msg_type, content);
715 } else if (msg_type === 'status') {
715 } else if (msg_type === 'status') {
716 if (content.execution_state === 'busy') {
716 if (content.execution_state === 'busy') {
717 IPython.kernel_status_widget.status_busy();
717 IPython.kernel_status_widget.status_busy();
718 } else if (content.execution_state === 'idle') {
718 } else if (content.execution_state === 'idle') {
719 IPython.kernel_status_widget.status_idle();
719 IPython.kernel_status_widget.status_idle();
720 } else if (content.execution_state === 'dead') {
720 } else if (content.execution_state === 'dead') {
721 this.handle_status_dead();
721 this.handle_status_dead();
722 };
722 };
723 }
723 }
724 };
724 };
725
725
726
726
727 Notebook.prototype.handle_status_dead = function () {
727 Notebook.prototype.handle_status_dead = function () {
728 var that = this;
728 var that = this;
729 this.kernel.stop_channels();
729 this.kernel.stop_channels();
730 var dialog = $('<div/>');
730 var dialog = $('<div/>');
731 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.');
731 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.');
732 $(document).append(dialog);
732 $(document).append(dialog);
733 dialog.dialog({
733 dialog.dialog({
734 resizable: false,
734 resizable: false,
735 modal: true,
735 modal: true,
736 title: "Dead kernel",
736 title: "Dead kernel",
737 buttons : {
737 buttons : {
738 "Yes": function () {
738 "Restart": function () {
739 that.start_kernel();
739 that.start_kernel();
740 $(this).dialog('close');
740 $(this).dialog('close');
741 },
741 },
742 "No": function () {
742 "Continue running": function () {
743 $(this).dialog('close');
743 $(this).dialog('close');
744 }
744 }
745 }
745 }
746 });
746 });
747 };
747 };
748
748
749
749
750 Notebook.prototype.handle_output = function (cell, msg_type, content) {
750 Notebook.prototype.handle_output = function (cell, msg_type, content) {
751 var json = {};
751 var json = {};
752 json.output_type = msg_type;
752 json.output_type = msg_type;
753 if (msg_type === "stream") {
753 if (msg_type === "stream") {
754 json.text = utils.fixConsole(content.data);
754 json.text = utils.fixConsole(content.data);
755 json.stream = content.name;
755 json.stream = content.name;
756 } else if (msg_type === "display_data") {
756 } else if (msg_type === "display_data") {
757 json = this.convert_mime_types(json, content.data);
757 json = this.convert_mime_types(json, content.data);
758 } else if (msg_type === "pyout") {
758 } else if (msg_type === "pyout") {
759 json.prompt_number = content.execution_count;
759 json.prompt_number = content.execution_count;
760 json = this.convert_mime_types(json, content.data);
760 json = this.convert_mime_types(json, content.data);
761 } else if (msg_type === "pyerr") {
761 } else if (msg_type === "pyerr") {
762 json.ename = content.ename;
762 json.ename = content.ename;
763 json.evalue = content.evalue;
763 json.evalue = content.evalue;
764 var traceback = [];
764 var traceback = [];
765 for (var i=0; i<content.traceback.length; i++) {
765 for (var i=0; i<content.traceback.length; i++) {
766 traceback.push(utils.fixConsole(content.traceback[i]));
766 traceback.push(utils.fixConsole(content.traceback[i]));
767 }
767 }
768 json.traceback = traceback;
768 json.traceback = traceback;
769 };
769 };
770 cell.append_output(json);
770 cell.append_output(json);
771 this.dirty = true;
771 this.dirty = true;
772 };
772 };
773
773
774
774
775 Notebook.prototype.convert_mime_types = function (json, data) {
775 Notebook.prototype.convert_mime_types = function (json, data) {
776 if (data['text/plain'] !== undefined) {
776 if (data['text/plain'] !== undefined) {
777 json.text = utils.fixConsole(data['text/plain']);
777 json.text = utils.fixConsole(data['text/plain']);
778 };
778 };
779 if (data['text/html'] !== undefined) {
779 if (data['text/html'] !== undefined) {
780 json.html = data['text/html'];
780 json.html = data['text/html'];
781 };
781 };
782 if (data['image/svg+xml'] !== undefined) {
782 if (data['image/svg+xml'] !== undefined) {
783 json.svg = data['image/svg+xml'];
783 json.svg = data['image/svg+xml'];
784 };
784 };
785 if (data['image/png'] !== undefined) {
785 if (data['image/png'] !== undefined) {
786 json.png = data['image/png'];
786 json.png = data['image/png'];
787 };
787 };
788 if (data['image/jpeg'] !== undefined) {
788 if (data['image/jpeg'] !== undefined) {
789 json.jpeg = data['image/jpeg'];
789 json.jpeg = data['image/jpeg'];
790 };
790 };
791 if (data['text/latex'] !== undefined) {
791 if (data['text/latex'] !== undefined) {
792 json.latex = data['text/latex'];
792 json.latex = data['text/latex'];
793 };
793 };
794 if (data['application/json'] !== undefined) {
794 if (data['application/json'] !== undefined) {
795 json.json = data['application/json'];
795 json.json = data['application/json'];
796 };
796 };
797 if (data['application/javascript'] !== undefined) {
797 if (data['application/javascript'] !== undefined) {
798 json.javascript = data['application/javascript'];
798 json.javascript = data['application/javascript'];
799 }
799 }
800 return json;
800 return json;
801 };
801 };
802
802
803
803
804 Notebook.prototype.execute_selected_cell = function (options) {
804 Notebook.prototype.execute_selected_cell = function (options) {
805 // add_new: should a new cell be added if we are at the end of the nb
805 // add_new: should a new cell be added if we are at the end of the nb
806 // terminal: execute in terminal mode, which stays in the current cell
806 // terminal: execute in terminal mode, which stays in the current cell
807 default_options = {terminal: false, add_new: true}
807 default_options = {terminal: false, add_new: true}
808 $.extend(default_options, options)
808 $.extend(default_options, options)
809 var that = this;
809 var that = this;
810 var cell = that.selected_cell();
810 var cell = that.selected_cell();
811 var cell_index = that.find_cell_index(cell);
811 var cell_index = that.find_cell_index(cell);
812 if (cell instanceof IPython.CodeCell) {
812 if (cell instanceof IPython.CodeCell) {
813 cell.clear_output();
813 cell.clear_output();
814 var code = cell.get_code();
814 var code = cell.get_code();
815 var msg_id = that.kernel.execute(cell.get_code());
815 var msg_id = that.kernel.execute(cell.get_code());
816 that.msg_cell_map[msg_id] = cell.cell_id;
816 that.msg_cell_map[msg_id] = cell.cell_id;
817 } else if (cell instanceof IPython.HTMLCell) {
817 } else if (cell instanceof IPython.HTMLCell) {
818 cell.render();
818 cell.render();
819 }
819 }
820 if (default_options.terminal) {
820 if (default_options.terminal) {
821 cell.select_all();
821 cell.select_all();
822 } else {
822 } else {
823 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
823 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
824 that.insert_code_cell_below();
824 that.insert_code_cell_below();
825 // If we are adding a new cell at the end, scroll down to show it.
825 // If we are adding a new cell at the end, scroll down to show it.
826 that.scroll_to_bottom();
826 that.scroll_to_bottom();
827 } else {
827 } else {
828 that.select(cell_index+1);
828 that.select(cell_index+1);
829 };
829 };
830 };
830 };
831 this.dirty = true;
831 this.dirty = true;
832 };
832 };
833
833
834
834
835 Notebook.prototype.execute_all_cells = function () {
835 Notebook.prototype.execute_all_cells = function () {
836 var ncells = this.ncells();
836 var ncells = this.ncells();
837 for (var i=0; i<ncells; i++) {
837 for (var i=0; i<ncells; i++) {
838 this.select(i);
838 this.select(i);
839 this.execute_selected_cell({add_new:false});
839 this.execute_selected_cell({add_new:false});
840 };
840 };
841 this.scroll_to_bottom();
841 this.scroll_to_bottom();
842 };
842 };
843
843
844
844
845 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
845 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
846 var msg_id = this.kernel.complete(line, cursor_pos);
846 var msg_id = this.kernel.complete(line, cursor_pos);
847 this.msg_cell_map[msg_id] = cell.cell_id;
847 this.msg_cell_map[msg_id] = cell.cell_id;
848 };
848 };
849
849
850 // Persistance and loading
850 // Persistance and loading
851
851
852
852
853 Notebook.prototype.fromJSON = function (data) {
853 Notebook.prototype.fromJSON = function (data) {
854 var ncells = this.ncells();
854 var ncells = this.ncells();
855 for (var i=0; i<ncells; i++) {
855 for (var i=0; i<ncells; i++) {
856 // Always delete cell 0 as they get renumbered as they are deleted.
856 // Always delete cell 0 as they get renumbered as they are deleted.
857 this.delete_cell(0);
857 this.delete_cell(0);
858 };
858 };
859 // Save the metadata
859 // Save the metadata
860 this.metadata = data.metadata;
860 this.metadata = data.metadata;
861 // Only handle 1 worksheet for now.
861 // Only handle 1 worksheet for now.
862 var worksheet = data.worksheets[0];
862 var worksheet = data.worksheets[0];
863 if (worksheet !== undefined) {
863 if (worksheet !== undefined) {
864 var new_cells = worksheet.cells;
864 var new_cells = worksheet.cells;
865 ncells = new_cells.length;
865 ncells = new_cells.length;
866 var cell_data = null;
866 var cell_data = null;
867 var new_cell = null;
867 var new_cell = null;
868 for (var i=0; i<ncells; i++) {
868 for (var i=0; i<ncells; i++) {
869 cell_data = new_cells[i];
869 cell_data = new_cells[i];
870 if (cell_data.cell_type == 'code') {
870 if (cell_data.cell_type == 'code') {
871 new_cell = this.insert_code_cell_below();
871 new_cell = this.insert_code_cell_below();
872 new_cell.fromJSON(cell_data);
872 new_cell.fromJSON(cell_data);
873 } else if (cell_data.cell_type === 'html') {
873 } else if (cell_data.cell_type === 'html') {
874 new_cell = this.insert_html_cell_below();
874 new_cell = this.insert_html_cell_below();
875 new_cell.fromJSON(cell_data);
875 new_cell.fromJSON(cell_data);
876 } else if (cell_data.cell_type === 'markdown') {
876 } else if (cell_data.cell_type === 'markdown') {
877 new_cell = this.insert_markdown_cell_below();
877 new_cell = this.insert_markdown_cell_below();
878 new_cell.fromJSON(cell_data);
878 new_cell.fromJSON(cell_data);
879 };
879 };
880 };
880 };
881 };
881 };
882 };
882 };
883
883
884
884
885 Notebook.prototype.toJSON = function () {
885 Notebook.prototype.toJSON = function () {
886 var cells = this.cells();
886 var cells = this.cells();
887 var ncells = cells.length;
887 var ncells = cells.length;
888 cell_array = new Array(ncells);
888 cell_array = new Array(ncells);
889 for (var i=0; i<ncells; i++) {
889 for (var i=0; i<ncells; i++) {
890 cell_array[i] = cells[i].toJSON();
890 cell_array[i] = cells[i].toJSON();
891 };
891 };
892 data = {
892 data = {
893 // Only handle 1 worksheet for now.
893 // Only handle 1 worksheet for now.
894 worksheets : [{cells:cell_array}],
894 worksheets : [{cells:cell_array}],
895 metadata : this.metadata
895 metadata : this.metadata
896 }
896 }
897 return data
897 return data
898 };
898 };
899
899
900 Notebook.prototype.save_notebook = function () {
900 Notebook.prototype.save_notebook = function () {
901 if (IPython.save_widget.test_notebook_name()) {
901 if (IPython.save_widget.test_notebook_name()) {
902 var notebook_id = IPython.save_widget.get_notebook_id();
902 var notebook_id = IPython.save_widget.get_notebook_id();
903 var nbname = IPython.save_widget.get_notebook_name();
903 var nbname = IPython.save_widget.get_notebook_name();
904 // We may want to move the name/id/nbformat logic inside toJSON?
904 // We may want to move the name/id/nbformat logic inside toJSON?
905 var data = this.toJSON();
905 var data = this.toJSON();
906 data.metadata.name = nbname;
906 data.metadata.name = nbname;
907 data.nbformat = 2;
907 data.nbformat = 2;
908 // We do the call with settings so we can set cache to false.
908 // We do the call with settings so we can set cache to false.
909 var settings = {
909 var settings = {
910 processData : false,
910 processData : false,
911 cache : false,
911 cache : false,
912 type : "PUT",
912 type : "PUT",
913 data : JSON.stringify(data),
913 data : JSON.stringify(data),
914 headers : {'Content-Type': 'application/json'},
914 headers : {'Content-Type': 'application/json'},
915 success : $.proxy(this.notebook_saved,this)
915 success : $.proxy(this.notebook_saved,this)
916 };
916 };
917 IPython.save_widget.status_saving();
917 IPython.save_widget.status_saving();
918 $.ajax("/notebooks/" + notebook_id, settings);
918 $.ajax("/notebooks/" + notebook_id, settings);
919 };
919 };
920 };
920 };
921
921
922
922
923 Notebook.prototype.notebook_saved = function (data, status, xhr) {
923 Notebook.prototype.notebook_saved = function (data, status, xhr) {
924 this.dirty = false;
924 this.dirty = false;
925 setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500);
925 setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500);
926 }
926 }
927
927
928
928
929 Notebook.prototype.load_notebook = function (callback) {
929 Notebook.prototype.load_notebook = function (callback) {
930 var that = this;
930 var that = this;
931 var notebook_id = IPython.save_widget.get_notebook_id();
931 var notebook_id = IPython.save_widget.get_notebook_id();
932 // We do the call with settings so we can set cache to false.
932 // We do the call with settings so we can set cache to false.
933 var settings = {
933 var settings = {
934 processData : false,
934 processData : false,
935 cache : false,
935 cache : false,
936 type : "GET",
936 type : "GET",
937 dataType : "json",
937 dataType : "json",
938 success : function (data, status, xhr) {
938 success : function (data, status, xhr) {
939 that.notebook_loaded(data, status, xhr);
939 that.notebook_loaded(data, status, xhr);
940 if (callback !== undefined) {
940 if (callback !== undefined) {
941 callback();
941 callback();
942 };
942 };
943 }
943 }
944 };
944 };
945 IPython.save_widget.status_loading();
945 IPython.save_widget.status_loading();
946 $.ajax("/notebooks/" + notebook_id, settings);
946 $.ajax("/notebooks/" + notebook_id, settings);
947 }
947 }
948
948
949
949
950 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
950 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
951 this.fromJSON(data);
951 this.fromJSON(data);
952 if (this.ncells() === 0) {
952 if (this.ncells() === 0) {
953 this.insert_code_cell_below();
953 this.insert_code_cell_below();
954 };
954 };
955 IPython.save_widget.status_save();
955 IPython.save_widget.status_save();
956 IPython.save_widget.set_notebook_name(data.metadata.name);
956 IPython.save_widget.set_notebook_name(data.metadata.name);
957 this.start_kernel();
957 this.start_kernel();
958 this.dirty = false;
958 this.dirty = false;
959 // fromJSON always selects the last cell inserted. We need to wait
959 // fromJSON always selects the last cell inserted. We need to wait
960 // until that is done before scrolling to the top.
960 // until that is done before scrolling to the top.
961 setTimeout(function () {
961 setTimeout(function () {
962 IPython.notebook.select(0);
962 IPython.notebook.select(0);
963 IPython.notebook.scroll_to_top();
963 IPython.notebook.scroll_to_top();
964 }, 50);
964 }, 50);
965 };
965 };
966
966
967 IPython.Notebook = Notebook;
967 IPython.Notebook = Notebook;
968
968
969 return IPython;
969 return IPython;
970
970
971 }(IPython));
971 }(IPython));
972
972
General Comments 0
You need to be logged in to leave comments. Login now