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