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