##// END OF EJS Templates
Further work updating JS URL scheme to use data-base-project-url.
Brian E. Granger -
Show More
@@ -1,166 +1,165 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Kernel
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13
14 14 var utils = IPython.utils;
15 15
16 16 var Kernel = function () {
17 17 this.kernel_id = null;
18 18 this.shell_channel = null;
19 19 this.iopub_channel = null;
20 20 this.base_url = $('body').data('baseKernelUrl') + "kernels";
21 21 this.running = false;
22 22 this.username = "username";
23 23 this.session_id = utils.uuid();
24 24
25 25 if (typeof(WebSocket) !== 'undefined') {
26 26 this.WebSocket = WebSocket
27 27 } else if (typeof(MozWebSocket) !== 'undefined') {
28 28 this.WebSocket = MozWebSocket
29 29 } else {
30 30 alert('Your browser does not have WebSocket support, please try Chrome, Safari or Firefox 6. Firefox 4 and 5 are also supported by you have to enable WebSockets in about:config.');
31 31 };
32 32 };
33 33
34 34
35 35 Kernel.prototype.get_msg = function (msg_type, content) {
36 36 var msg = {
37 37 header : {
38 38 msg_id : utils.uuid(),
39 39 username : this.username,
40 40 session : this.session_id,
41 41 msg_type : msg_type
42 42 },
43 43 content : content,
44 44 parent_header : {}
45 45 };
46 46 return msg;
47 47 }
48 48
49 49 Kernel.prototype.start = function (notebook_id, callback) {
50 50 var that = this;
51 51 if (!this.running) {
52 52 var qs = $.param({notebook:notebook_id});
53 53 var url = this.base_url + '?' + qs
54 54 $.post(url,
55 55 function (kernel_id) {
56 56 that._handle_start_kernel(kernel_id, callback);
57 57 },
58 58 'json'
59 59 );
60 60 };
61 61 };
62 62
63 63
64 64 Kernel.prototype.restart = function (callback) {
65 65 IPython.kernel_status_widget.status_restarting();
66 66 var url = this.kernel_url + "/restart";
67 67 var that = this;
68 68 if (this.running) {
69 69 this.stop_channels();
70 70 $.post(url,
71 71 function (kernel_id) {
72 72 that._handle_start_kernel(kernel_id, callback);
73 73 },
74 74 'json'
75 75 );
76 76 };
77 77 };
78 78
79 79
80 80 Kernel.prototype._handle_start_kernel = function (json, callback) {
81 81 this.running = true;
82 82 this.kernel_id = json.kernel_id;
83 83 this.ws_url = json.ws_url;
84 84 this.kernel_url = this.base_url + "/" + this.kernel_id;
85 85 this.start_channels();
86 86 callback();
87 87 IPython.kernel_status_widget.status_idle();
88 88 };
89 89
90 90
91 91 Kernel.prototype.start_channels = function () {
92 92 this.stop_channels();
93 93 var ws_url = this.ws_url + this.kernel_url;
94 94 console.log("Starting WS:", ws_url);
95 95 this.shell_channel = new this.WebSocket(ws_url + "/shell");
96 96 this.iopub_channel = new this.WebSocket(ws_url + "/iopub");
97 97 send_cookie = function(){
98 98 this.send(document.cookie);
99 console.log(this);
100 99 }
101 100 this.shell_channel.onopen = send_cookie;
102 101 this.iopub_channel.onopen = send_cookie;
103 102 };
104 103
105 104
106 105 Kernel.prototype.stop_channels = function () {
107 106 if (this.shell_channel !== null) {
108 107 this.shell_channel.close();
109 108 this.shell_channel = null;
110 109 };
111 110 if (this.iopub_channel !== null) {
112 111 this.iopub_channel.close();
113 112 this.iopub_channel = null;
114 113 };
115 114 };
116 115
117 116 Kernel.prototype.execute = function (code) {
118 117 var content = {
119 118 code : code,
120 119 silent : false,
121 120 user_variables : [],
122 121 user_expressions : {},
123 122 allow_stdin : false,
124 123 };
125 124 var msg = this.get_msg("execute_request", content);
126 125 this.shell_channel.send(JSON.stringify(msg));
127 126 return msg.header.msg_id;
128 127 }
129 128
130 129
131 130 Kernel.prototype.complete = function (line, cursor_pos) {
132 131 var content = {
133 132 text : '',
134 133 line : line,
135 134 cursor_pos : cursor_pos
136 135 };
137 136 var msg = this.get_msg("complete_request", content);
138 137 this.shell_channel.send(JSON.stringify(msg));
139 138 return msg.header.msg_id;
140 139 }
141 140
142 141
143 142 Kernel.prototype.interrupt = function () {
144 143 if (this.running) {
145 144 $.post(this.kernel_url + "/interrupt");
146 145 };
147 146 };
148 147
149 148
150 149 Kernel.prototype.kill = function () {
151 150 if (this.running) {
152 151 this.running = false;
153 152 var settings = {
154 153 cache : false,
155 154 type : "DELETE",
156 155 };
157 156 $.ajax(this.kernel_url, settings);
158 157 };
159 158 };
160 159
161 160 IPython.Kernel = Kernel;
162 161
163 162 return IPython;
164 163
165 164 }(IPython));
166 165
@@ -1,39 +1,39 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // On document ready
10 10 //============================================================================
11 11
12 12
13 13 $(document).ready(function () {
14 14
15 15 $('div#header').addClass('border-box-sizing');
16 16 $('div#header_border').addClass('border-box-sizing ui-widget ui-widget-content');
17 17
18 18 $('div#main_app').addClass('border-box-sizing ui-widget');
19 19 $('div#app_hbox').addClass('hbox');
20 20
21 21 $('div#content_toolbar').addClass('ui-widget ui-helper-clearfix');
22 22
23 23 $('#new_notebook').button().click(function (e) {
24 window.open('/new');
24 window.open($('body').data('baseProjectUrl')+'new');
25 25 });
26 26
27 27 $('div#left_panel').addClass('box-flex');
28 28 $('div#right_panel').addClass('box-flex');
29 29
30 30 IPython.notebook_list = new IPython.NotebookList('div#notebook_list');
31 31 IPython.notebook_list.load_list();
32 32
33 33 // These have display: none in the css file and are made visible here to prevent FLOUC.
34 34 $('div#header').css('display','block');
35 35 $('div#main_app').css('display','block');
36 36
37 37
38 38 });
39 39
@@ -1,997 +1,999 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Notebook
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13
14 14 var utils = IPython.utils;
15 15
16 16 var Notebook = function (selector) {
17 17 this.element = $(selector);
18 18 this.element.scroll();
19 19 this.element.data("notebook", this);
20 20 this.next_prompt_number = 1;
21 21 this.kernel = null;
22 22 this.dirty = false;
23 23 this.msg_cell_map = {};
24 24 this.metadata = {};
25 25 this.control_key_active = false;
26 26 this.style();
27 27 this.create_elements();
28 28 this.bind_events();
29 29 };
30 30
31 31
32 32 Notebook.prototype.style = function () {
33 33 $('div#notebook').addClass('border-box-sizing');
34 34 };
35 35
36 36
37 37 Notebook.prototype.create_elements = function () {
38 38 // We add this end_space div to the end of the notebook div to:
39 39 // i) provide a margin between the last cell and the end of the notebook
40 40 // ii) to prevent the div from scrolling up when the last cell is being
41 41 // edited, but is too low on the page, which browsers will do automatically.
42 42 var that = this;
43 43 var end_space = $('<div class="end_space"></div>').height(150);
44 44 end_space.dblclick(function (e) {
45 45 var ncells = that.ncells();
46 46 that.insert_code_cell_below(ncells-1);
47 47 });
48 48 this.element.append(end_space);
49 49 $('div#notebook').addClass('border-box-sizing');
50 50 };
51 51
52 52
53 53 Notebook.prototype.bind_events = function () {
54 54 var that = this;
55 55 $(document).keydown(function (event) {
56 56 // console.log(event);
57 57 if (event.which === 38) {
58 58 var cell = that.selected_cell();
59 59 if (cell.at_top()) {
60 60 event.preventDefault();
61 61 that.select_prev();
62 62 };
63 63 } else if (event.which === 40) {
64 64 var cell = that.selected_cell();
65 65 if (cell.at_bottom()) {
66 66 event.preventDefault();
67 67 that.select_next();
68 68 };
69 69 } else if (event.which === 13 && event.shiftKey) {
70 70 that.execute_selected_cell();
71 71 return false;
72 72 } else if (event.which === 13 && event.ctrlKey) {
73 73 that.execute_selected_cell({terminal:true});
74 74 return false;
75 75 } else if (event.which === 77 && event.ctrlKey) {
76 76 that.control_key_active = true;
77 77 return false;
78 78 } else if (event.which === 68 && that.control_key_active) {
79 79 // Delete selected cell = d
80 80 that.delete_cell();
81 81 that.control_key_active = false;
82 82 return false;
83 83 } else if (event.which === 65 && that.control_key_active) {
84 84 // Insert code cell above selected = a
85 85 that.insert_code_cell_above();
86 86 that.control_key_active = false;
87 87 return false;
88 88 } else if (event.which === 66 && that.control_key_active) {
89 89 // Insert code cell below selected = b
90 90 that.insert_code_cell_below();
91 91 that.control_key_active = false;
92 92 return false;
93 93 } else if (event.which === 67 && that.control_key_active) {
94 94 // To code = c
95 95 that.to_code();
96 96 that.control_key_active = false;
97 97 return false;
98 98 } else if (event.which === 77 && that.control_key_active) {
99 99 // To markdown = m
100 100 that.to_markdown();
101 101 that.control_key_active = false;
102 102 return false;
103 103 } else if (event.which === 84 && that.control_key_active) {
104 104 // Toggle output = t
105 105 that.toggle_output();
106 106 that.control_key_active = false;
107 107 return false;
108 108 } else if (event.which === 83 && that.control_key_active) {
109 109 // Save notebook = s
110 110 IPython.save_widget.save_notebook();
111 111 that.control_key_active = false;
112 112 return false;
113 113 } else if (event.which === 74 && that.control_key_active) {
114 114 // Move cell down = j
115 115 that.move_cell_down();
116 116 that.control_key_active = false;
117 117 return false;
118 118 } else if (event.which === 75 && that.control_key_active) {
119 119 // Move cell up = k
120 120 that.move_cell_up();
121 121 that.control_key_active = false;
122 122 return false;
123 123 } else if (event.which === 80 && that.control_key_active) {
124 124 // Select previous = p
125 125 that.select_prev();
126 126 that.control_key_active = false;
127 127 return false;
128 128 } else if (event.which === 78 && that.control_key_active) {
129 129 // Select next = n
130 130 that.select_next();
131 131 that.control_key_active = false;
132 132 return false;
133 133 } else if (event.which === 76 && that.control_key_active) {
134 134 // Toggle line numbers = l
135 135 that.cell_toggle_line_numbers();
136 136 that.control_key_active = false;
137 137 return false;
138 138 } else if (event.which === 73 && that.control_key_active) {
139 139 // Interrupt kernel = i
140 140 IPython.notebook.kernel.interrupt();
141 141 that.control_key_active = false;
142 142 return false;
143 143 } else if (event.which === 190 && that.control_key_active) {
144 144 // Restart kernel = . # matches qt console
145 145 IPython.notebook.restart_kernel();
146 146 that.control_key_active = false;
147 147 return false;
148 148 } else if (event.which === 72 && that.control_key_active) {
149 149 // Show keyboard shortcuts = h
150 150 that.toggle_keyboard_shortcuts();
151 151 that.control_key_active = false;
152 152 return false;
153 153 } else if (that.control_key_active) {
154 154 that.control_key_active = false;
155 155 return true;
156 156 };
157 157 });
158 158
159 159 this.element.bind('collapse_pager', function () {
160 160 var app_height = $('div#main_app').height(); // content height
161 161 var splitter_height = $('div#pager_splitter').outerHeight(true);
162 162 var new_height = app_height - splitter_height;
163 163 that.element.animate({height : new_height + 'px'}, 'fast');
164 164 });
165 165
166 166 this.element.bind('expand_pager', function () {
167 167 var app_height = $('div#main_app').height(); // content height
168 168 var splitter_height = $('div#pager_splitter').outerHeight(true);
169 169 var pager_height = $('div#pager').outerHeight(true);
170 170 var new_height = app_height - pager_height - splitter_height;
171 171 that.element.animate({height : new_height + 'px'}, 'fast');
172 172 });
173 173
174 174 this.element.bind('collapse_left_panel', function () {
175 175 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
176 176 var new_margin = splitter_width;
177 177 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
178 178 });
179 179
180 180 this.element.bind('expand_left_panel', function () {
181 181 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
182 182 var left_panel_width = IPython.left_panel.width;
183 183 var new_margin = splitter_width + left_panel_width;
184 184 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
185 185 });
186 186
187 187 $(window).bind('beforeunload', function () {
188 188 var kill_kernel = $('#kill_kernel').prop('checked');
189 189 if (kill_kernel) {
190 190 that.kernel.kill();
191 191 }
192 192 if (that.dirty) {
193 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 199 Notebook.prototype.toggle_keyboard_shortcuts = function () {
200 200 // toggles display of keyboard shortcut dialog
201 201 var that = this;
202 202 if ( this.shortcut_dialog ){
203 203 // if dialog is already shown, close it
204 204 this.shortcut_dialog.dialog("close");
205 205 this.shortcut_dialog = null;
206 206 return;
207 207 }
208 208 var dialog = $('<div/>');
209 209 this.shortcut_dialog = dialog;
210 210 var shortcuts = [
211 211 {key: 'Shift-Enter', help: 'run cell'},
212 212 {key: 'Ctrl-Enter', help: 'run cell in-place'},
213 213 {key: 'Ctrl-m d', help: 'delete cell'},
214 214 {key: 'Ctrl-m a', help: 'insert cell above'},
215 215 {key: 'Ctrl-m b', help: 'insert cell below'},
216 216 {key: 'Ctrl-m t', help: 'toggle output'},
217 217 {key: 'Ctrl-m l', help: 'toggle line numbers'},
218 218 {key: 'Ctrl-m s', help: 'save notebook'},
219 219 {key: 'Ctrl-m j', help: 'move cell down'},
220 220 {key: 'Ctrl-m k', help: 'move cell up'},
221 221 {key: 'Ctrl-m c', help: 'code cell'},
222 222 {key: 'Ctrl-m m', help: 'markdown cell'},
223 223 {key: 'Ctrl-m p', help: 'select previous'},
224 224 {key: 'Ctrl-m n', help: 'select next'},
225 225 {key: 'Ctrl-m i', help: 'interrupt kernel'},
226 226 {key: 'Ctrl-m .', help: 'restart kernel'},
227 227 {key: 'Ctrl-m h', help: 'show keyboard shortcuts'}
228 228 ];
229 229 for (var i=0; i<shortcuts.length; i++) {
230 230 dialog.append($('<div>').
231 231 append($('<span/>').addClass('shortcut_key').html(shortcuts[i].key)).
232 232 append($('<span/>').addClass('shortcut_descr').html(' : ' + shortcuts[i].help))
233 233 );
234 234 };
235 235 dialog.bind('dialogclose', function(event) {
236 236 // dialog has been closed, allow it to be drawn again.
237 237 that.shortcut_dialog = null;
238 238 });
239 239 dialog.dialog({title: 'Keyboard shortcuts'});
240 240 };
241 241
242 242
243 243 Notebook.prototype.scroll_to_bottom = function () {
244 244 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
245 245 };
246 246
247 247
248 248 Notebook.prototype.scroll_to_top = function () {
249 249 this.element.animate({scrollTop:0}, 0);
250 250 };
251 251
252 252
253 253 // Cell indexing, retrieval, etc.
254 254
255 255
256 256 Notebook.prototype.cell_elements = function () {
257 257 return this.element.children("div.cell");
258 258 }
259 259
260 260
261 261 Notebook.prototype.ncells = function (cell) {
262 262 return this.cell_elements().length;
263 263 }
264 264
265 265
266 266 // TODO: we are often calling cells as cells()[i], which we should optimize
267 267 // to cells(i) or a new method.
268 268 Notebook.prototype.cells = function () {
269 269 return this.cell_elements().toArray().map(function (e) {
270 270 return $(e).data("cell");
271 271 });
272 272 }
273 273
274 274
275 275 Notebook.prototype.find_cell_index = function (cell) {
276 276 var result = null;
277 277 this.cell_elements().filter(function (index) {
278 278 if ($(this).data("cell") === cell) {
279 279 result = index;
280 280 };
281 281 });
282 282 return result;
283 283 };
284 284
285 285
286 286 Notebook.prototype.index_or_selected = function (index) {
287 287 return index || this.selected_index() || 0;
288 288 }
289 289
290 290
291 291 Notebook.prototype.select = function (index) {
292 292 if (index !== undefined && index >= 0 && index < this.ncells()) {
293 293 if (this.selected_index() !== null) {
294 294 this.selected_cell().unselect();
295 295 };
296 296 this.cells()[index].select();
297 297 };
298 298 return this;
299 299 };
300 300
301 301
302 302 Notebook.prototype.select_next = function () {
303 303 var index = this.selected_index();
304 304 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
305 305 this.select(index+1);
306 306 };
307 307 return this;
308 308 };
309 309
310 310
311 311 Notebook.prototype.select_prev = function () {
312 312 var index = this.selected_index();
313 313 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
314 314 this.select(index-1);
315 315 };
316 316 return this;
317 317 };
318 318
319 319
320 320 Notebook.prototype.selected_index = function () {
321 321 var result = null;
322 322 this.cell_elements().filter(function (index) {
323 323 if ($(this).data("cell").selected === true) {
324 324 result = index;
325 325 };
326 326 });
327 327 return result;
328 328 };
329 329
330 330
331 331 Notebook.prototype.cell_for_msg = function (msg_id) {
332 332 var cell_id = this.msg_cell_map[msg_id];
333 333 var result = null;
334 334 this.cell_elements().filter(function (index) {
335 335 cell = $(this).data("cell");
336 336 if (cell.cell_id === cell_id) {
337 337 result = cell;
338 338 };
339 339 });
340 340 return result;
341 341 };
342 342
343 343
344 344 Notebook.prototype.selected_cell = function () {
345 345 return this.cell_elements().eq(this.selected_index()).data("cell");
346 346 }
347 347
348 348
349 349 // Cell insertion, deletion and moving.
350 350
351 351
352 352 Notebook.prototype.delete_cell = function (index) {
353 353 var i = index || this.selected_index();
354 354 if (i !== null && i >= 0 && i < this.ncells()) {
355 355 this.cell_elements().eq(i).remove();
356 356 if (i === (this.ncells())) {
357 357 this.select(i-1);
358 358 } else {
359 359 this.select(i);
360 360 };
361 361 };
362 362 this.dirty = true;
363 363 return this;
364 364 };
365 365
366 366
367 367 Notebook.prototype.append_cell = function (cell) {
368 368 this.element.find('div.end_space').before(cell.element);
369 369 this.dirty = true;
370 370 return this;
371 371 };
372 372
373 373
374 374 Notebook.prototype.insert_cell_below = function (cell, index) {
375 375 var ncells = this.ncells();
376 376 if (ncells === 0) {
377 377 this.append_cell(cell);
378 378 return this;
379 379 };
380 380 if (index >= 0 && index < ncells) {
381 381 this.cell_elements().eq(index).after(cell.element);
382 382 };
383 383 this.dirty = true;
384 384 return this
385 385 };
386 386
387 387
388 388 Notebook.prototype.insert_cell_above = function (cell, index) {
389 389 var ncells = this.ncells();
390 390 if (ncells === 0) {
391 391 this.append_cell(cell);
392 392 return this;
393 393 };
394 394 if (index >= 0 && index < ncells) {
395 395 this.cell_elements().eq(index).before(cell.element);
396 396 };
397 397 this.dirty = true;
398 398 return this;
399 399 };
400 400
401 401
402 402 Notebook.prototype.move_cell_up = function (index) {
403 403 var i = index || this.selected_index();
404 404 if (i !== null && i < this.ncells() && i > 0) {
405 405 var pivot = this.cell_elements().eq(i-1);
406 406 var tomove = this.cell_elements().eq(i);
407 407 if (pivot !== null && tomove !== null) {
408 408 tomove.detach();
409 409 pivot.before(tomove);
410 410 this.select(i-1);
411 411 };
412 412 };
413 413 this.dirty = true;
414 414 return this;
415 415 }
416 416
417 417
418 418 Notebook.prototype.move_cell_down = function (index) {
419 419 var i = index || this.selected_index();
420 420 if (i !== null && i < (this.ncells()-1) && i >= 0) {
421 421 var pivot = this.cell_elements().eq(i+1)
422 422 var tomove = this.cell_elements().eq(i)
423 423 if (pivot !== null && tomove !== null) {
424 424 tomove.detach();
425 425 pivot.after(tomove);
426 426 this.select(i+1);
427 427 };
428 428 };
429 429 this.dirty = true;
430 430 return this;
431 431 }
432 432
433 433
434 434 Notebook.prototype.sort_cells = function () {
435 435 var ncells = this.ncells();
436 436 var sindex = this.selected_index();
437 437 var swapped;
438 438 do {
439 439 swapped = false
440 440 for (var i=1; i<ncells; i++) {
441 441 current = this.cell_elements().eq(i).data("cell");
442 442 previous = this.cell_elements().eq(i-1).data("cell");
443 443 if (previous.input_prompt_number > current.input_prompt_number) {
444 444 this.move_cell_up(i);
445 445 swapped = true;
446 446 };
447 447 };
448 448 } while (swapped);
449 449 this.select(sindex);
450 450 return this;
451 451 };
452 452
453 453
454 454 Notebook.prototype.insert_code_cell_above = function (index) {
455 455 // TODO: Bounds check for i
456 456 var i = this.index_or_selected(index);
457 457 var cell = new IPython.CodeCell(this);
458 458 cell.set_input_prompt();
459 459 this.insert_cell_above(cell, i);
460 460 this.select(this.find_cell_index(cell));
461 461 return cell;
462 462 }
463 463
464 464
465 465 Notebook.prototype.insert_code_cell_below = function (index) {
466 466 // TODO: Bounds check for i
467 467 var i = this.index_or_selected(index);
468 468 var cell = new IPython.CodeCell(this);
469 469 cell.set_input_prompt();
470 470 this.insert_cell_below(cell, i);
471 471 this.select(this.find_cell_index(cell));
472 472 return cell;
473 473 }
474 474
475 475
476 476 Notebook.prototype.insert_html_cell_above = function (index) {
477 477 // TODO: Bounds check for i
478 478 var i = this.index_or_selected(index);
479 479 var cell = new IPython.HTMLCell(this);
480 480 cell.config_mathjax();
481 481 this.insert_cell_above(cell, i);
482 482 this.select(this.find_cell_index(cell));
483 483 return cell;
484 484 }
485 485
486 486
487 487 Notebook.prototype.insert_html_cell_below = function (index) {
488 488 // TODO: Bounds check for i
489 489 var i = this.index_or_selected(index);
490 490 var cell = new IPython.HTMLCell(this);
491 491 cell.config_mathjax();
492 492 this.insert_cell_below(cell, i);
493 493 this.select(this.find_cell_index(cell));
494 494 return cell;
495 495 }
496 496
497 497
498 498 Notebook.prototype.insert_markdown_cell_above = function (index) {
499 499 // TODO: Bounds check for i
500 500 var i = this.index_or_selected(index);
501 501 var cell = new IPython.MarkdownCell(this);
502 502 cell.config_mathjax();
503 503 this.insert_cell_above(cell, i);
504 504 this.select(this.find_cell_index(cell));
505 505 return cell;
506 506 }
507 507
508 508
509 509 Notebook.prototype.insert_markdown_cell_below = function (index) {
510 510 // TODO: Bounds check for i
511 511 var i = this.index_or_selected(index);
512 512 var cell = new IPython.MarkdownCell(this);
513 513 cell.config_mathjax();
514 514 this.insert_cell_below(cell, i);
515 515 this.select(this.find_cell_index(cell));
516 516 return cell;
517 517 }
518 518
519 519
520 520 Notebook.prototype.to_code = function (index) {
521 521 // TODO: Bounds check for i
522 522 var i = this.index_or_selected(index);
523 523 var source_element = this.cell_elements().eq(i);
524 524 var source_cell = source_element.data("cell");
525 525 if (source_cell instanceof IPython.HTMLCell ||
526 526 source_cell instanceof IPython.MarkdownCell) {
527 527 this.insert_code_cell_below(i);
528 528 var target_cell = this.cells()[i+1];
529 529 target_cell.set_code(source_cell.get_source());
530 530 source_element.remove();
531 531 target_cell.select();
532 532 };
533 533 this.dirty = true;
534 534 };
535 535
536 536
537 537 Notebook.prototype.to_markdown = function (index) {
538 538 // TODO: Bounds check for i
539 539 var i = this.index_or_selected(index);
540 540 var source_element = this.cell_elements().eq(i);
541 541 var source_cell = source_element.data("cell");
542 542 var target_cell = null;
543 543 if (source_cell instanceof IPython.CodeCell) {
544 544 this.insert_markdown_cell_below(i);
545 545 var target_cell = this.cells()[i+1];
546 546 var text = source_cell.get_code();
547 547 } else if (source_cell instanceof IPython.HTMLCell) {
548 548 this.insert_markdown_cell_below(i);
549 549 var target_cell = this.cells()[i+1];
550 550 var text = source_cell.get_source();
551 551 if (text === source_cell.placeholder) {
552 552 text = target_cell.placeholder;
553 553 }
554 554 }
555 555 if (target_cell !== null) {
556 556 if (text === "") {text = target_cell.placeholder;};
557 557 target_cell.set_source(text);
558 558 source_element.remove();
559 559 target_cell.edit();
560 560 }
561 561 this.dirty = true;
562 562 };
563 563
564 564
565 565 Notebook.prototype.to_html = function (index) {
566 566 // TODO: Bounds check for i
567 567 var i = this.index_or_selected(index);
568 568 var source_element = this.cell_elements().eq(i);
569 569 var source_cell = source_element.data("cell");
570 570 var target_cell = null;
571 571 if (source_cell instanceof IPython.CodeCell) {
572 572 this.insert_html_cell_below(i);
573 573 var target_cell = this.cells()[i+1];
574 574 var text = source_cell.get_code();
575 575 } else if (source_cell instanceof IPython.MarkdownCell) {
576 576 this.insert_html_cell_below(i);
577 577 var target_cell = this.cells()[i+1];
578 578 var text = source_cell.get_source();
579 579 if (text === source_cell.placeholder) {
580 580 text = target_cell.placeholder;
581 581 }
582 582 }
583 583 if (target_cell !== null) {
584 584 if (text === "") {text = target_cell.placeholder;};
585 585 target_cell.set_source(text);
586 586 source_element.remove();
587 587 target_cell.edit();
588 588 }
589 589 this.dirty = true;
590 590 };
591 591
592 592
593 593 // Cell collapsing and output clearing
594 594
595 595 Notebook.prototype.collapse = function (index) {
596 596 var i = this.index_or_selected(index);
597 597 this.cells()[i].collapse();
598 598 this.dirty = true;
599 599 };
600 600
601 601
602 602 Notebook.prototype.expand = function (index) {
603 603 var i = this.index_or_selected(index);
604 604 this.cells()[i].expand();
605 605 this.dirty = true;
606 606 };
607 607
608 608
609 609 Notebook.prototype.toggle_output = function (index) {
610 610 var i = this.index_or_selected(index);
611 611 this.cells()[i].toggle_output();
612 612 this.dirty = true;
613 613 };
614 614
615 615
616 616 Notebook.prototype.set_autoindent = function (state) {
617 617 var cells = this.cells();
618 618 len = cells.length;
619 619 for (var i=0; i<len; i++) {
620 620 cells[i].set_autoindent(state)
621 621 };
622 622 };
623 623
624 624
625 625 Notebook.prototype.clear_all_output = function () {
626 626 var ncells = this.ncells();
627 627 var cells = this.cells();
628 628 for (var i=0; i<ncells; i++) {
629 629 if (cells[i] instanceof IPython.CodeCell) {
630 630 cells[i].clear_output();
631 631 }
632 632 };
633 633 this.dirty = true;
634 634 };
635 635
636 636 // Other cell functions: line numbers, ...
637 637
638 638 Notebook.prototype.cell_toggle_line_numbers = function() {
639 639 this.selected_cell().toggle_line_numbers()
640 640 };
641 641
642 642 // Kernel related things
643 643
644 644 Notebook.prototype.start_kernel = function () {
645 645 this.kernel = new IPython.Kernel();
646 646 var notebook_id = IPython.save_widget.get_notebook_id();
647 647 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
648 648 };
649 649
650 650
651 651 Notebook.prototype.restart_kernel = function () {
652 652 var that = this;
653 653 var notebook_id = IPython.save_widget.get_notebook_id();
654 654
655 655 var dialog = $('<div/>');
656 656 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
657 657 $(document).append(dialog);
658 658 dialog.dialog({
659 659 resizable: false,
660 660 modal: true,
661 661 title: "Restart kernel or continue running?",
662 662 buttons : {
663 663 "Restart": function () {
664 664 that.kernel.restart($.proxy(that.kernel_started, that));
665 665 $(this).dialog('close');
666 666 },
667 667 "Continue running": function () {
668 668 $(this).dialog('close');
669 669 }
670 670 }
671 671 });
672 672 };
673 673
674 674
675 675 Notebook.prototype.kernel_started = function () {
676 676 console.log("Kernel started: ", this.kernel.kernel_id);
677 677 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
678 678 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
679 679 };
680 680
681 681
682 682 Notebook.prototype.handle_shell_reply = function (e) {
683 683 reply = $.parseJSON(e.data);
684 684 var header = reply.header;
685 685 var content = reply.content;
686 686 var msg_type = header.msg_type;
687 687 // console.log(reply);
688 688 var cell = this.cell_for_msg(reply.parent_header.msg_id);
689 689 if (msg_type === "execute_reply") {
690 690 cell.set_input_prompt(content.execution_count);
691 691 this.dirty = true;
692 692 } else if (msg_type === "complete_reply") {
693 693 cell.finish_completing(content.matched_text, content.matches);
694 694 };
695 695 var payload = content.payload || [];
696 696 this.handle_payload(cell, payload);
697 697 };
698 698
699 699
700 700 Notebook.prototype.handle_payload = function (cell, payload) {
701 701 var l = payload.length;
702 702 for (var i=0; i<l; i++) {
703 703 if (payload[i].source === 'IPython.zmq.page.page') {
704 704 if (payload[i].text.trim() !== '') {
705 705 IPython.pager.clear();
706 706 IPython.pager.expand();
707 707 IPython.pager.append_text(payload[i].text);
708 708 }
709 709 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
710 710 var index = this.find_cell_index(cell);
711 711 var new_cell = this.insert_code_cell_below(index);
712 712 new_cell.set_code(payload[i].text);
713 713 this.dirty = true;
714 714 }
715 715 };
716 716 };
717 717
718 718
719 719 Notebook.prototype.handle_iopub_reply = function (e) {
720 720 reply = $.parseJSON(e.data);
721 721 var content = reply.content;
722 722 // console.log(reply);
723 723 var msg_type = reply.header.msg_type;
724 724 var cell = this.cell_for_msg(reply.parent_header.msg_id);
725 725 var output_types = ['stream','display_data','pyout','pyerr'];
726 726 if (output_types.indexOf(msg_type) >= 0) {
727 727 this.handle_output(cell, msg_type, content);
728 728 } else if (msg_type === 'status') {
729 729 if (content.execution_state === 'busy') {
730 730 IPython.kernel_status_widget.status_busy();
731 731 } else if (content.execution_state === 'idle') {
732 732 IPython.kernel_status_widget.status_idle();
733 733 } else if (content.execution_state === 'dead') {
734 734 this.handle_status_dead();
735 735 };
736 736 }
737 737 };
738 738
739 739
740 740 Notebook.prototype.handle_status_dead = function () {
741 741 var that = this;
742 742 this.kernel.stop_channels();
743 743 var dialog = $('<div/>');
744 744 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.');
745 745 $(document).append(dialog);
746 746 dialog.dialog({
747 747 resizable: false,
748 748 modal: true,
749 749 title: "Dead kernel",
750 750 buttons : {
751 751 "Restart": function () {
752 752 that.start_kernel();
753 753 $(this).dialog('close');
754 754 },
755 755 "Continue running": function () {
756 756 $(this).dialog('close');
757 757 }
758 758 }
759 759 });
760 760 };
761 761
762 762
763 763 Notebook.prototype.handle_output = function (cell, msg_type, content) {
764 764 var json = {};
765 765 json.output_type = msg_type;
766 766 if (msg_type === "stream") {
767 767 json.text = utils.fixConsole(content.data);
768 768 json.stream = content.name;
769 769 } else if (msg_type === "display_data") {
770 770 json = this.convert_mime_types(json, content.data);
771 771 } else if (msg_type === "pyout") {
772 772 json.prompt_number = content.execution_count;
773 773 json = this.convert_mime_types(json, content.data);
774 774 } else if (msg_type === "pyerr") {
775 775 json.ename = content.ename;
776 776 json.evalue = content.evalue;
777 777 var traceback = [];
778 778 for (var i=0; i<content.traceback.length; i++) {
779 779 traceback.push(utils.fixConsole(content.traceback[i]));
780 780 }
781 781 json.traceback = traceback;
782 782 };
783 783 cell.append_output(json);
784 784 this.dirty = true;
785 785 };
786 786
787 787
788 788 Notebook.prototype.convert_mime_types = function (json, data) {
789 789 if (data['text/plain'] !== undefined) {
790 790 json.text = utils.fixConsole(data['text/plain']);
791 791 };
792 792 if (data['text/html'] !== undefined) {
793 793 json.html = data['text/html'];
794 794 };
795 795 if (data['image/svg+xml'] !== undefined) {
796 796 json.svg = data['image/svg+xml'];
797 797 };
798 798 if (data['image/png'] !== undefined) {
799 799 json.png = data['image/png'];
800 800 };
801 801 if (data['image/jpeg'] !== undefined) {
802 802 json.jpeg = data['image/jpeg'];
803 803 };
804 804 if (data['text/latex'] !== undefined) {
805 805 json.latex = data['text/latex'];
806 806 };
807 807 if (data['application/json'] !== undefined) {
808 808 json.json = data['application/json'];
809 809 };
810 810 if (data['application/javascript'] !== undefined) {
811 811 json.javascript = data['application/javascript'];
812 812 }
813 813 return json;
814 814 };
815 815
816 816
817 817 Notebook.prototype.execute_selected_cell = function (options) {
818 818 // add_new: should a new cell be added if we are at the end of the nb
819 819 // terminal: execute in terminal mode, which stays in the current cell
820 820 default_options = {terminal: false, add_new: true}
821 821 $.extend(default_options, options)
822 822 var that = this;
823 823 var cell = that.selected_cell();
824 824 var cell_index = that.find_cell_index(cell);
825 825 if (cell instanceof IPython.CodeCell) {
826 826 cell.clear_output();
827 827 var code = cell.get_code();
828 828 var msg_id = that.kernel.execute(cell.get_code());
829 829 that.msg_cell_map[msg_id] = cell.cell_id;
830 830 } else if (cell instanceof IPython.HTMLCell) {
831 831 cell.render();
832 832 }
833 833 if (default_options.terminal) {
834 834 cell.select_all();
835 835 } else {
836 836 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
837 837 that.insert_code_cell_below();
838 838 // If we are adding a new cell at the end, scroll down to show it.
839 839 that.scroll_to_bottom();
840 840 } else {
841 841 that.select(cell_index+1);
842 842 };
843 843 };
844 844 this.dirty = true;
845 845 };
846 846
847 847
848 848 Notebook.prototype.execute_all_cells = function () {
849 849 var ncells = this.ncells();
850 850 for (var i=0; i<ncells; i++) {
851 851 this.select(i);
852 852 this.execute_selected_cell({add_new:false});
853 853 };
854 854 this.scroll_to_bottom();
855 855 };
856 856
857 857
858 858 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
859 859 var msg_id = this.kernel.complete(line, cursor_pos);
860 860 this.msg_cell_map[msg_id] = cell.cell_id;
861 861 };
862 862
863 863 // Persistance and loading
864 864
865 865
866 866 Notebook.prototype.fromJSON = function (data) {
867 867 var ncells = this.ncells();
868 868 for (var i=0; i<ncells; i++) {
869 869 // Always delete cell 0 as they get renumbered as they are deleted.
870 870 this.delete_cell(0);
871 871 };
872 872 // Save the metadata
873 873 this.metadata = data.metadata;
874 874 // Only handle 1 worksheet for now.
875 875 var worksheet = data.worksheets[0];
876 876 if (worksheet !== undefined) {
877 877 var new_cells = worksheet.cells;
878 878 ncells = new_cells.length;
879 879 var cell_data = null;
880 880 var new_cell = null;
881 881 for (var i=0; i<ncells; i++) {
882 882 cell_data = new_cells[i];
883 883 if (cell_data.cell_type == 'code') {
884 884 new_cell = this.insert_code_cell_below();
885 885 new_cell.fromJSON(cell_data);
886 886 } else if (cell_data.cell_type === 'html') {
887 887 new_cell = this.insert_html_cell_below();
888 888 new_cell.fromJSON(cell_data);
889 889 } else if (cell_data.cell_type === 'markdown') {
890 890 new_cell = this.insert_markdown_cell_below();
891 891 new_cell.fromJSON(cell_data);
892 892 };
893 893 };
894 894 };
895 895 };
896 896
897 897
898 898 Notebook.prototype.toJSON = function () {
899 899 var cells = this.cells();
900 900 var ncells = cells.length;
901 901 cell_array = new Array(ncells);
902 902 for (var i=0; i<ncells; i++) {
903 903 cell_array[i] = cells[i].toJSON();
904 904 };
905 905 data = {
906 906 // Only handle 1 worksheet for now.
907 907 worksheets : [{cells:cell_array}],
908 908 metadata : this.metadata
909 909 }
910 910 return data
911 911 };
912 912
913 913 Notebook.prototype.save_notebook = function () {
914 914 if (IPython.save_widget.test_notebook_name()) {
915 915 var notebook_id = IPython.save_widget.get_notebook_id();
916 916 var nbname = IPython.save_widget.get_notebook_name();
917 917 // We may want to move the name/id/nbformat logic inside toJSON?
918 918 var data = this.toJSON();
919 919 data.metadata.name = nbname;
920 920 data.nbformat = 2;
921 921 // We do the call with settings so we can set cache to false.
922 922 var settings = {
923 923 processData : false,
924 924 cache : false,
925 925 type : "PUT",
926 926 data : JSON.stringify(data),
927 927 headers : {'Content-Type': 'application/json'},
928 928 success : $.proxy(this.notebook_saved,this),
929 929 error : $.proxy(this.notebook_save_failed,this)
930 930 };
931 931 IPython.save_widget.status_saving();
932 932 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
933 933 $.ajax(url, settings);
934 934 };
935 935 };
936 936
937 937
938 938 Notebook.prototype.notebook_saved = function (data, status, xhr) {
939 939 this.dirty = false;
940 940 IPython.save_widget.notebook_saved();
941 941 setTimeout($.proxy(IPython.save_widget.status_save,IPython.save_widget),500);
942 942 }
943 943
944 944
945 945 Notebook.prototype.notebook_save_failed = function (xhr, status, error_msg) {
946 946 // Notify the user and reset the save button
947 947 // TODO: Handle different types of errors (timeout etc.)
948 948 alert('An unexpected error occured while saving the notebook.');
949 949 setTimeout($.proxy(IPython.save_widget.reset_status,IPython.save_widget),500);
950 950 }
951 951
952 952
953 953 Notebook.prototype.load_notebook = function (callback) {
954 954 var that = this;
955 955 var notebook_id = IPython.save_widget.get_notebook_id();
956 956 // We do the call with settings so we can set cache to false.
957 957 var settings = {
958 958 processData : false,
959 959 cache : false,
960 960 type : "GET",
961 961 dataType : "json",
962 962 success : function (data, status, xhr) {
963 963 that.notebook_loaded(data, status, xhr);
964 964 if (callback !== undefined) {
965 965 callback();
966 966 };
967 967 }
968 968 };
969 969 IPython.save_widget.status_loading();
970 970 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id
971 971 $.ajax(url, settings);
972 972 }
973 973
974 974
975 975 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
976 976 this.fromJSON(data);
977 977 if (this.ncells() === 0) {
978 978 this.insert_code_cell_below();
979 979 };
980 980 IPython.save_widget.status_save();
981 981 IPython.save_widget.set_notebook_name(data.metadata.name);
982 982 this.start_kernel();
983 983 this.dirty = false;
984 984 // fromJSON always selects the last cell inserted. We need to wait
985 985 // until that is done before scrolling to the top.
986 986 setTimeout(function () {
987 987 IPython.notebook.select(0);
988 988 IPython.notebook.scroll_to_top();
989 989 }, 50);
990 990 };
991 991
992
992 993 IPython.Notebook = Notebook;
993 994
995
994 996 return IPython;
995 997
996 998 }(IPython));
997 999
@@ -1,287 +1,287 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // PanelSection
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13
14 14 var utils = IPython.utils;
15 15
16 16 // Base PanelSection class
17 17
18 18 var PanelSection = function (selector) {
19 19 this.selector = selector;
20 20 if (this.selector !== undefined) {
21 21 this.element = $(selector);
22 22 this.header = this.element.find('h3.section_header');
23 23 this.content = this.element.find('div.section_content');
24 24 this.style();
25 25 this.bind_events();
26 26 }
27 27 this.expanded = true;
28 28 };
29 29
30 30
31 31 PanelSection.prototype.style = function () {
32 32 this.header.addClass('ui-widget ui-state-default');
33 33 this.header.attr('title', "Click to Show/Hide Section");
34 34 this.content.addClass('ui-widget section_content');
35 35 };
36 36
37 37
38 38 PanelSection.prototype.bind_events = function () {
39 39 var that = this;
40 40 this.header.click(function () {
41 41 that.toggle();
42 42 });
43 43 this.header.hover(function () {
44 44 that.header.toggleClass('ui-state-hover');
45 45 });
46 46 };
47 47
48 48
49 49 PanelSection.prototype.expand = function () {
50 50 if (!this.expanded) {
51 51 this.content.slideDown('fast');
52 52 this.expanded = true;
53 53 };
54 54 };
55 55
56 56
57 57 PanelSection.prototype.collapse = function () {
58 58 if (this.expanded) {
59 59 this.content.slideUp('fast');
60 60 this.expanded = false;
61 61 };
62 62 };
63 63
64 64
65 65 PanelSection.prototype.toggle = function () {
66 66 if (this.expanded === true) {
67 67 this.collapse();
68 68 } else {
69 69 this.expand();
70 70 };
71 71 };
72 72
73 73
74 74 PanelSection.prototype.create_children = function () {};
75 75
76 76
77 77 // NotebookSection
78 78
79 79 var NotebookSection = function () {
80 80 PanelSection.apply(this, arguments);
81 81 };
82 82
83 83
84 84 NotebookSection.prototype = new PanelSection();
85 85
86 86
87 87 NotebookSection.prototype.style = function () {
88 88 PanelSection.prototype.style.apply(this);
89 89 this.content.addClass('ui-helper-clearfix');
90 90 this.content.find('div.section_row').addClass('ui-helper-clearfix');
91 91 this.content.find('#new_open').buttonset();
92 92 this.content.find('#new_notebook').attr('title', "Create a new notebook");
93 93 this.content.find('#open_notebook').attr('title', "Open an existing notebook");
94 94 this.content.find('#download_notebook').button();
95 95 this.content.find('#download_notebook').attr('title',
96 96 "Download the notebook in the specified format," +
97 97 " either full ipynb notebook or as a Python script.");
98 98 // upload notebook doesn't exist:
99 99 this.content.find('#upload_notebook').button();
100 100 this.content.find('#download_format').addClass('ui-widget ui-widget-content');
101 101 this.content.find('#download_format option').addClass('ui-widget ui-widget-content');
102 102 };
103 103
104 104
105 105 NotebookSection.prototype.bind_events = function () {
106 106 PanelSection.prototype.bind_events.apply(this);
107 107 var that = this;
108 108 this.content.find('#new_notebook').click(function () {
109 window.open('/new');
109 window.open($('body').data('baseProjectUrl')+'new');
110 110 });
111 111 this.content.find('#open_notebook').click(function () {
112 window.open('/');
112 window.open($('body').data('baseProjectUrl'));
113 113 });
114 114 this.content.find('#download_notebook').click(function () {
115 115 var format = that.content.find('#download_format').val();
116 116 var notebook_id = IPython.save_widget.get_notebook_id();
117 var url = '/notebooks/' + notebook_id + '?format=' + format;
117 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id + '?format=' + format;
118 118 window.open(url,'_newtab');
119 119 });
120 120 };
121 121
122 122 // CellSection
123 123
124 124 var CellSection = function () {
125 125 PanelSection.apply(this, arguments);
126 126 };
127 127
128 128
129 129 CellSection.prototype = new PanelSection();
130 130
131 131
132 132 CellSection.prototype.style = function () {
133 133 PanelSection.prototype.style.apply(this);
134 134 this.content.addClass('ui-helper-clearfix');
135 135 this.content.find('div.section_row').addClass('ui-helper-clearfix');
136 136 this.content.find('#delete_cell').button();
137 137 this.content.find('#delete_cell').attr('title', "Delete the selected cell");
138 138
139 139 this.content.find('#insert').buttonset();
140 140 this.content.find('#insert_cell_above').attr('title', "Insert new cell above selected");
141 141 this.content.find('#insert_cell_below').attr('title', "Insert new cell below selected");
142 142
143 143 this.content.find('#move').buttonset();
144 144 this.content.find('#move_cell_up').attr('title', "Move selected cell up one in the Notebook");
145 145 this.content.find('#move_cell_down').attr('title', "Move selected cell down one in the Notebook");
146 146
147 147 this.content.find('#cell_type').buttonset();
148 148 this.content.find('#to_markdown').attr('title', 'Change selected cell to markdown (for text)')
149 149 this.content.find('#to_code').attr('title', 'Change selected cell to code (for execution)')
150 150
151 151 this.content.find('#cell_output').buttonset();
152 152 this.content.find('#toggle_output').attr('title', 'Toggle visibility of the output of code cells')
153 153 this.content.find('#clear_all_output').attr('title', 'Clear output of all code cells (actually removes the data, unlike toggle)')
154 154
155 155 this.content.find('#run_cells').buttonset();
156 156 this.content.find('#run_selected_cell').attr('title', 'Submit the selected cell for execution')
157 157 this.content.find('#run_all_cells').attr('title', 'Run *all* code cells in the notebook in order')
158 158 this.content.find('#autoindent').attr('title', 'Autoindent code as-you-type')
159 159 this.content.find('#autoindent_label').attr('title', 'Autoindent code as-you-type')
160 160 };
161 161
162 162
163 163 CellSection.prototype.bind_events = function () {
164 164 PanelSection.prototype.bind_events.apply(this);
165 165 this.content.find('#toggle_output').click(function () {
166 166 IPython.notebook.toggle_output();
167 167 });
168 168 this.content.find('#clear_all_output').click(function () {
169 169 IPython.notebook.clear_all_output();
170 170 });
171 171 this.content.find('#delete_cell').click(function () {
172 172 IPython.notebook.delete_cell();
173 173 });
174 174 this.content.find('#insert_cell_above').click(function () {
175 175 IPython.notebook.insert_code_cell_above();
176 176 });
177 177 this.content.find('#insert_cell_below').click(function () {
178 178 IPython.notebook.insert_code_cell_below();
179 179 });
180 180 this.content.find('#move_cell_up').click(function () {
181 181 IPython.notebook.move_cell_up();
182 182 });
183 183 this.content.find('#move_cell_down').click(function () {
184 184 IPython.notebook.move_cell_down();
185 185 });
186 186 this.content.find('#to_code').click(function () {
187 187 IPython.notebook.to_code();
188 188 });
189 189 this.content.find('#to_markdown').click(function () {
190 190 IPython.notebook.to_markdown();
191 191 });
192 192 this.content.find('#run_selected_cell').click(function () {
193 193 IPython.notebook.execute_selected_cell();
194 194 });
195 195 this.content.find('#run_all_cells').click(function () {
196 196 IPython.notebook.execute_all_cells();
197 197 });
198 198 this.content.find('#autoindent').change(function () {
199 199 var state = $('#autoindent').prop('checked');
200 200 IPython.notebook.set_autoindent(state);
201 201 });
202 202 };
203 203
204 204
205 205 // KernelSection
206 206
207 207 var KernelSection = function () {
208 208 PanelSection.apply(this, arguments);
209 209 };
210 210
211 211
212 212 KernelSection.prototype = new PanelSection();
213 213
214 214
215 215 KernelSection.prototype.style = function () {
216 216 PanelSection.prototype.style.apply(this);
217 217 this.content.addClass('ui-helper-clearfix');
218 218 this.content.find('div.section_row').addClass('ui-helper-clearfix');
219 219 this.content.find('#int_restart').buttonset();
220 220 this.content.find("#int_kernel").attr('title', "Interrupt the kernel with SIGINT/Ctrl-C");
221 221 this.content.find("#restart_kernel").attr('title',
222 222 "Restart the kernel. This will shutdown the current kernel," +
223 223 " and start a new, clean kernel in its place, connected to this Notebook." +
224 224 " This may break the connection of other clients connected to this kernel." );
225 225 var kill_tip = "Kill the kernel on exit. If unchecked, the kernel will remain" +
226 226 " active after closing the session, allowing you to reconnect and resume later.";
227 227 this.content.find('#kill_kernel').attr('title', kill_tip);
228 228 this.content.find('#kill_kernel_label').attr('title', kill_tip);
229 229
230 230 };
231 231
232 232
233 233 KernelSection.prototype.bind_events = function () {
234 234 PanelSection.prototype.bind_events.apply(this);
235 235 this.content.find('#restart_kernel').click(function () {
236 236 IPython.notebook.restart_kernel();
237 237 });
238 238 this.content.find('#int_kernel').click(function () {
239 239 IPython.notebook.kernel.interrupt();
240 240 });
241 241 };
242 242
243 243
244 244 // HelpSection
245 245
246 246 var HelpSection = function () {
247 247 PanelSection.apply(this, arguments);
248 248 };
249 249
250 250
251 251 HelpSection.prototype = new PanelSection();
252 252
253 253
254 254 HelpSection.prototype.style = function () {
255 255 PanelSection.prototype.style.apply(this);
256 256 PanelSection.prototype.style.apply(this);
257 257 this.content.addClass('ui-helper-clearfix');
258 258 this.content.find('div.section_row').addClass('ui-helper-clearfix');
259 259 this.content.find('#help_buttons0').buttonset();
260 260 this.content.find('#help_buttons1').buttonset();
261 261 this.content.find('#help_buttons2').buttonset();
262 262 this.content.find('#python_help').attr('title', "Open the online Python documentation in a new tab")
263 263 this.content.find('#ipython_help').attr('title', "Open the online IPython documentation in a new tab")
264 264 this.content.find('#numpy_help').attr('title', "Open the online NumPy documentation in a new tab")
265 265 this.content.find('#scipy_help').attr('title', "Open the online SciPy documentation in a new tab")
266 266 this.content.find('#matplotlib_help').attr('title', "Open the online Matplotlib documentation in a new tab")
267 267 this.content.find('#sympy_help').attr('title', "Open the online SymPy documentation in a new tab")
268 268 };
269 269
270 270
271 271 HelpSection.prototype.bind_events = function () {
272 272 PanelSection.prototype.bind_events.apply(this);
273 273 };
274 274
275 275
276 276 // Set module variables
277 277
278 278 IPython.PanelSection = PanelSection;
279 279 IPython.NotebookSection = NotebookSection;
280 280 IPython.CellSection = CellSection;
281 281 IPython.KernelSection = KernelSection;
282 282 IPython.HelpSection = HelpSection;
283 283
284 284 return IPython;
285 285
286 286 }(IPython));
287 287
@@ -1,279 +1,278 b''
1 1 <!DOCTYPE HTML>
2 2 <html>
3 3
4 4 <head>
5 5 <meta charset="utf-8">
6 6
7 7 <title>IPython Notebook</title>
8 8
9 9 <!-- <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script> -->
10 10 <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script>
11 11 <script type="text/javascript">
12 12 function CheckMathJax(){
13 13 var div=document.getElementById("MathJaxFetchingWarning")
14 14 if(window.MathJax){
15 15 document.body.removeChild(div)
16 16 }
17 17 else{
18 18 div.style.display = "block";
19 19 }
20 20 }
21 21 if (typeof MathJax == 'undefined') {
22 22 console.log("No local MathJax, loading from CDN");
23 23 document.write(unescape("%3Cscript type='text/javascript' src='http://cdn.mathjax.org/mathjax/latest/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
24 24 }else{
25 25 console.log("Using local MathJax");
26 26 }
27 27 </script>
28 28
29 29 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
30 30 <link rel="stylesheet" href="static/codemirror/lib/codemirror.css">
31 31 <link rel="stylesheet" href="static/codemirror/mode/markdown/markdown.css">
32 32 <link rel="stylesheet" href="static/codemirror/mode/rst/rst.css">
33 33 <link rel="stylesheet" href="static/codemirror/theme/ipython.css">
34 34 <link rel="stylesheet" href="static/codemirror/theme/default.css">
35 35
36 36 <link rel="stylesheet" href="static/prettify/prettify.css"/>
37 37
38 38 <link rel="stylesheet" href="static/css/boilerplate.css" type="text/css" />
39 39 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
40 40 <link rel="stylesheet" href="static/css/base.css" type="text/css" />
41 41 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
42 42 <link rel="stylesheet" href="static/css/renderedhtml.css" type="text/css" />
43 43
44 44
45 45 </head>
46 46
47 47 <body onload='CheckMathJax();'
48 48 data-project={{project}} data-notebook-id={{notebook_id}}
49 49 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
50 50 >
51 51
52 52 <div id="header">
53 53 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
54 54 <span id="save_widget">
55 55 <input type="text" id="notebook_name" size="20"></textarea>
56 56 <button id="save_notebook"><u>S</u>ave</button>
57 57 </span>
58 58 <span id="quick_help_area">
59 59 <button id="quick_help">Quick<u>H</u>elp</button>
60 60 </span>
61 61 <span id="kernel_status">Idle</span>
62 62 </div>
63 63
64 64 <div id="MathJaxFetchingWarning"
65 65 style="width:80%; margin:auto;padding-top:20%;text-align: justify; display:none">
66 66 <p style="font-size:26px;">There was an issue trying to fetch MathJax.js
67 67 from the internet.</p>
68 68
69 69 <p style="padding:0.2em"> With a working internet connection, you can run
70 70 the following at a Python or IPython prompt, which will install a local
71 71 copy of MathJax:</p>
72 72
73 73 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
74 74 from IPython.external import mathjax; mathjax.install_mathjax()
75 75 </pre>
76 76 This will try to install MathJax into the directory where you installed
77 77 IPython. If you installed IPython to a location that requires
78 78 administrative privileges to write, you will need to make this call as
79 79 an administrator. On OSX/Linux/Unix, this can be done at the
80 80 command-line via:
81 81 <pre style="background-color:lightblue;border:thin silver solid;padding:0.4em">
82 82 sudo python -c "from IPython.external import mathjax; mathjax.install_mathjax()"
83 83 </pre>
84 84 </p>
85 85 </div>
86 86
87 87 <div id="main_app">
88 88
89 89 <div id="left_panel">
90 90
91 91 <div id="notebook_section">
92 92 <h3 class="section_header">Notebook</h3>
93 93 <div class="section_content">
94 94 <div class="section_row">
95 95 <span id="new_open" class="section_row_buttons">
96 96 <button id="new_notebook">New</button>
97 97 <button id="open_notebook">Open</button>
98 98 </span>
99 99 <span class="section_row_header">Actions</span>
100 100 </div>
101 101 <div class="section_row">
102 102 <span>
103 103 <select id="download_format">
104 104 <option value="json">ipynb</option>
105 105 <option value="py">py</option>
106 106 </select>
107 107 </span>
108 108 <span class="section_row_buttons">
109 109 <button id="download_notebook">Download</button>
110 110 </span>
111 111 </div>
112 112 <div class="section_row">
113 113 <span class="section_row_buttons">
114 114 <span id="print_widget">
115 115 <button id="print_notebook">Print</button>
116 116 </span>
117 117 </span>
118 118 </div>
119 119 </div>
120 120 </div>
121 121
122 122 <div id="cell_section">
123 123 <h3 class="section_header">Cell</h3>
124 124 <div class="section_content">
125 125 <div class="section_row">
126 126 <span class="section_row_buttons">
127 127 <button id="delete_cell"><u>D</u>elete</button>
128 128 </span>
129 129 <span class="section_row_header">Actions</span>
130 130 </div>
131 131 <div class="section_row">
132 132 <span id="cell_type" class="section_row_buttons">
133 133 <button id="to_code"><u>C</u>ode</button>
134 134 <!-- <button id="to_html">HTML</button>-->
135 135 <button id="to_markdown"><u>M</u>arkdown</button>
136 136 </span>
137 137 <span class="button_label">Format</span>
138 138 </div>
139 139 <div class="section_row">
140 140 <span id="cell_output" class="section_row_buttons">
141 141 <button id="toggle_output"><u>T</u>oggle</button>
142 142 <button id="clear_all_output">ClearAll</button>
143 143 </span>
144 144 <span class="button_label">Output</span>
145 145 </div>
146 146 <div class="section_row">
147 147 <span id="insert" class="section_row_buttons">
148 148 <button id="insert_cell_above"><u>A</u>bove</button>
149 149 <button id="insert_cell_below"><u>B</u>elow</button>
150 150 </span>
151 151 <span class="button_label">Insert</span>
152 152 </div>
153 153 <div class="section_row">
154 154 <span id="move" class="section_row_buttons">
155 155 <button id="move_cell_up">Up</button>
156 156 <button id="move_cell_down">Down</button>
157 157 </span>
158 158 <span class="button_label">Move</span>
159 159 </div>
160 160 <div class="section_row">
161 161 <span id="run_cells" class="section_row_buttons">
162 162 <button id="run_selected_cell">Selected</button>
163 163 <button id="run_all_cells">All</button>
164 164 </span>
165 165 <span class="button_label">Run</span>
166 166 </div>
167 167 <div class="section_row">
168 168 <span id="autoindent_span">
169 169 <input type="checkbox" id="autoindent" checked="true"></input>
170 170 </span>
171 171 <span class="checkbox_label" id="autoindent_label">Autoindent:</span>
172 172 </div>
173 173 </div>
174 174 </div>
175 175
176 176 <div id="kernel_section">
177 177 <h3 class="section_header">Kernel</h3>
178 178 <div class="section_content">
179 179 <div class="section_row">
180 180 <span id="int_restart" class="section_row_buttons">
181 181 <button id="int_kernel"><u>I</u>nterrupt</button>
182 182 <button id="restart_kernel">Restart</button>
183 183 </span>
184 184 <span class="section_row_header">Actions</span>
185 185 </div>
186 186 <div class="section_row">
187 187 <span id="kernel_persist">
188 188 <input type="checkbox" id="kill_kernel"></input>
189 189 </span>
190 190 <span class="checkbox_label" id="kill_kernel_label">Kill kernel upon exit:</span>
191 191 </div>
192 192 </div>
193 193 </div>
194 194
195 195 <div id="help_section">
196 196 <h3 class="section_header">Help</h3>
197 197 <div class="section_content">
198 198 <div class="section_row">
199 199 <span id="help_buttons0" class="section_row_buttons">
200 200 <a id="python_help" href="http://docs.python.org" target="_blank">Python</a>
201 201 <a id="ipython_help" href="http://ipython.org/documentation.html" target="_blank">IPython</a>
202 202 </span>
203 203 <span class="section_row_header">Links</span>
204 204 </div>
205 205 <div class="section_row">
206 206 <span id="help_buttons1" class="section_row_buttons">
207 207 <a id="numpy_help" href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a>
208 208 <a id="scipy_help" href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a>
209 209 </span>
210 210 </div>
211 211 <div class="section_row">
212 212 <span id="help_buttons2" class="section_row_buttons">
213 213 <a id="matplotlib_help" href="http://matplotlib.sourceforge.net/" target="_blank">MPL</a>
214 214 <a id="sympy_help" href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a>
215 215 </span>
216 216 </div>
217 217 <div class="section_row">
218 218 <span class="help_string">run selected cell</span>
219 219 <span class="help_string_label">Shift-Enter :</span>
220 220 </div>
221 221 <div class="section_row">
222 222 <span class="help_string">run selected cell in-place</span>
223 223 <span class="help_string_label">Ctrl-Enter :</span>
224 224 </div>
225 225 <div class="section_row">
226 226 <span class="help_string">show keyboard shortcuts</span>
227 227 <span class="help_string_label">Ctrl-m h :</span>
228 228 </div>
229 229 </div>
230 230 </div>
231 231
232 232 </div>
233 233 <div id="left_panel_splitter"></div>
234 234 <div id="notebook_panel">
235 235 <div id="notebook"></div>
236 236 <div id="pager_splitter"></div>
237 237 <div id="pager"></div>
238 238 </div>
239 239
240 240 </div>
241 241
242 242 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
243 243 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
244 244 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
245 245
246 246 <script src="static/codemirror/lib/codemirror.js" charset="utf-8"></script>
247 247 <script src="static/codemirror/mode/python/python.js" charset="utf-8"></script>
248 248 <script src="static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
249 249 <script src="static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
250 250 <script src="static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
251 251 <script src="static/codemirror/mode/css/css.js" charset="utf-8"></script>
252 252 <script src="static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
253 253 <script src="static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
254 254
255 255 <script src="static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
256 256
257 257 <script src="static/prettify/prettify.js" charset="utf-8"></script>
258 258
259 259 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
260 260 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
261 261 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
262 262 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
263 263 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
264 264 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
265 265 <script src="static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
266 266 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
267 267 <script src="static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
268 268 <script src="static/js/quickhelp.js" type="text/javascript" charset="utf-8"></script>
269 269 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
270 270 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
271 271 <script src="static/js/printwidget.js" type="text/javascript" charset="utf-8"></script>
272 272 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
273 273 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
274 274 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
275 275
276
277 276 </body>
278 277
279 278 </html>
General Comments 0
You need to be logged in to leave comments. Login now