##// END OF EJS Templates
Adding note about vbox related scroll bugs.
Brian E. Granger -
Show More
@@ -1,238 +1,239
1 1 /**
2 2 * HTML5 ✰ Boilerplate
3 3 *
4 4 * style.css contains a reset, font normalization and some base styles.
5 5 *
6 6 * Credit is left where credit is due.
7 7 * Much inspiration was taken from these projects:
8 8 * - yui.yahooapis.com/2.8.1/build/base/base.css
9 9 * - camendesign.com/design/
10 10 * - praegnanz.de/weblog/htmlcssjs-kickstart
11 11 */
12 12
13 13
14 14 /**
15 15 * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
16 16 * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
17 17 * html5doctor.com/html-5-reset-stylesheet/
18 18 */
19 19
20 20 html, body, div, span, object, iframe,
21 21 h1, h2, h3, h4, h5, h6, p, blockquote, pre,
22 22 abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
23 23 small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
24 24 fieldset, form, label, legend,
25 25 table, caption, tbody, tfoot, thead, tr, th, td,
26 26 article, aside, canvas, details, figcaption, figure,
27 27 footer, header, hgroup, menu, nav, section, summary,
28 28 time, mark, audio, video {
29 29 margin: 0;
30 30 padding: 0;
31 31 border: 0;
32 32 /* font-size: 100%;*/
33 33 font: inherit;
34 34 vertical-align: baseline;
35 35 }
36 36
37 37 article, aside, details, figcaption, figure,
38 38 footer, header, hgroup, menu, nav, section {
39 39 display: block;
40 40 }
41 41
42 42 blockquote, q { quotes: none; }
43 43
44 44 blockquote:before, blockquote:after,
45 45 q:before, q:after { content: ""; content: none; }
46 46
47 47 ins { background-color: #ff9; color: #000; text-decoration: none; }
48 48
49 49 mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
50 50
51 51 del { text-decoration: line-through; }
52 52
53 53 abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
54 54
55 55 table { border-collapse: collapse; border-spacing: 0; }
56 56
57 57 hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
58 58
59 59 input, select { vertical-align: middle; }
60 60
61 61 body {
62 62 background-color: white;
63 63 /* This won't propagate to all children so we also set it below */
64 64 font-size: 12pt;
65 65 /* This makes sure that the body covers the entire window and needs to
66 66 be in a different element than the display: box in wrapper below */
67 67 position: absolute;
68 68 left: 0px;
69 69 right: 0px;
70 70 top: 0px;
71 71 bottom: 0px;
72 72 overflow: hidden;
73 73 }
74 74
75 75 div#wrapper {
76 76 /* This is needed to make sure the wrapper fills the body */
77 77 width: 100%;
78 78 height: 100%;
79 79 }
80 80
81 81 span#ipython_notebook h1 {
82 82 font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
83 83 font-size: 22pt;
84 84 padding: 10px;
85 85 margin: 10px;
86 86 }
87 87
88 88 div#tools {
89 89 font-size: 11pt;
90 90 }
91 91
92 92 span#kernel_status {
93 93 position: absolute;
94 94 top: 12%;
95 95 right: 10px;
96 96 font-weight: bold;
97 97 }
98 98
99 99 .status_idle {
100 100 color: gray;
101 101 }
102 102
103 103 .status_busy {
104 104 color: red;
105 105 }
106 106
107 107 .status_restarting {
108 108 color: black;
109 109 }
110 110
111 111 div#notebook_app {
112 width: 100%;
112 113 }
113 114
114 115 div#left_panel {
115 116 width: 200px;
116 117 overflow-y: auto;
117 118 }
118 119
119 120 div#pager_splitter {
120 121 height: 7px;
121 122 }
122 123
123 124 div#left_panel_splitter {
124 125 width: 7px;
125 126 }
126 127
127 128 div#pager {
128 129 height: 200px;
129 130 overflow: auto;
130 131 padding: 15px;
131 132 }
132 133
133 134 div#notebook {
134 135 overflow-y: scroll;
135 136 overflow-x: auto;
136 137 padding: 0px 15px;
137 138 background-color: white;
138 139 font-size: 12pt;
139 140 }
140 141
141 142 .monospace-font {
142 143 font-family: monospace;
143 144 font-size: 12pt;
144 145 }
145 146
146 147 div.cell {
147 148 width: 100%;
148 149 padding: 5px;
149 150 /* This acts as a spacer between cells, that is outside the border */
150 151 margin: 15px 0px 15px 0px;
151 152 position: relative;
152 153 }
153 154
154 155 div.code_cell {
155 156 background-color: white;
156 157 }
157 158
158 159 div.prompt {
159 160 width: 90px;
160 161 padding: 0px;
161 162 margin: 0px;
162 163 }
163 164
164 165 div.input_prompt {
165 166 color: navy;
166 167 }
167 168
168 169 div.output {
169 170 /* This is a spacer between the input and output of each cell */
170 171 margin-top: 15px;
171 172 }
172 173
173 174 div.output_prompt {
174 175 color: darkred;
175 176 }
176 177
177 178 div.output_area {
178 179 text-align: left;
179 180 color: black;
180 181 }
181 182
182 183 div.output_latex {
183 184 /* Slightly bigger than the rest of the notebook */
184 185 font-size: 13pt;
185 186 }
186 187
187 188 div.output_png {
188 189 }
189 190
190 191 div.text_cell {
191 192 background-color: white;
192 193 }
193 194
194 195 textarea.text_cell_input {
195 196 /* Slightly bigger than the rest of the notebook */
196 197 font-size: 13pt;
197 198 outline: none;
198 199 resize: none;
199 200 width: inherit;
200 201 border-style: none;
201 202 padding: 0px;
202 203 margin: 0px;
203 204 color: black;
204 205 }
205 206
206 207 div.text_cell_render {
207 208 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
208 209 /* Slightly bigger than the rest of the notebook */
209 210 font-size: 13pt;
210 211 outline: none;
211 212 resize: none;
212 213 width: inherit;
213 214 border-style: none;
214 215 padding: 5px;
215 216 color: black;
216 217 }
217 218
218 219 div.text_cell_render em {font-style: italic;}
219 220 div.text_cell_render strong {font-weight: bold;}
220 221 div.text_cell_render u {text-decoration: underline;}
221 222 div.text_cell_render :link { text-decoration: underline }
222 223 div.text_cell_render :visited { text-decoration: underline }
223 224 div.text_cell_render h1 {font-size: 2.0em; margin: .67em 0; font-weight: bold;}
224 225 div.text_cell_render h2 {font-size: 1.5em; margin: .75em 0; font-weight: bold;}
225 226 div.text_cell_render h3 {font-size: 1.17em; margin: .83em 0; font-weight: bold;}
226 227 div.text_cell_render h4 {margin: 1.12em 0; font-weight: bold;}
227 228 div.text_cell_render h5 {font-size: .83em; margin: 1.5em 0; font-weight: bold;}
228 229 div.text_cell_render h6 {font-size: .75em; margin: 1.67em 0; font-weight: bold;}
229 230 div.text_cell_render ul {list-style:disc; margin-left: 40px;}
230 231 div.text_cell_render ul ul {list-style:square; margin-left: 40px;}
231 232 div.text_cell_render ul ul ul {list-style:circle; margin-left: 40px;}
232 233 div.text_cell_render ol {list-style:upper-roman; margin-left: 40px;}
233 234 div.text_cell_render ol ol {list-style:upper-alpha;}
234 235 div.text_cell_render ol ol ol {list-style:decimal;}
235 236 div.text_cell_render ol ol ol ol {list-style:lower-alpha;}
236 237 div.text_cell_render ol ol ol ol ol {list-style:lower-roman;}
237 238
238 239
@@ -1,542 +1,544
1 1
2 2 //============================================================================
3 3 // Notebook
4 4 //============================================================================
5 5
6 6 var IPython = (function (IPython) {
7 7
8 8 var utils = IPython.utils;
9 9
10 10 var Notebook = function (selector) {
11 11 this.element = $(selector);
12 12 this.element.scroll();
13 13 this.element.data("notebook", this);
14 14 this.next_prompt_number = 1;
15 15 this.kernel = null;
16 16 this.msg_cell_map = {};
17 17 this.filename = null;
18 18 this.notebook_load_re = /%notebook load/
19 19 this.notebook_save_re = /%notebook save/
20 20 this.notebook_filename_re = /(\w)+.ipynb/
21 21 this.style();
22 22 this.bind_events();
23 23 this.start_kernel();
24 24 };
25 25
26 26
27 27 Notebook.prototype.style = function () {
28 // With vbox here Chrome exhibits the CodeMirror scroll bug.
29 // Without the vbox here, Firefox won't scroll the notebook div.
28 30 this.element.addClass('vbox box-flex1 border-box-sizing');
29 31 };
30 32
31 33
32 34 Notebook.prototype.bind_events = function () {
33 35 var that = this;
34 36 $(document).keydown(function (event) {
35 37 // console.log(event);
36 38 if (event.which === 38) {
37 39 var cell = that.selected_cell();
38 40 if (cell.at_top()) {
39 41 event.preventDefault();
40 42 that.select_prev();
41 43 };
42 44 } else if (event.which === 40) {
43 45 var cell = that.selected_cell();
44 46 if (cell.at_bottom()) {
45 47 event.preventDefault();
46 48 that.select_next();
47 49 };
48 50 } else if (event.which === 13 && event.shiftKey) {
49 51 // The focus is not quite working here.
50 52 var cell = that.selected_cell();
51 53 var cell_index = that.find_cell_index(cell);
52 54 // TODO: the logic here needs to be moved into appropriate
53 55 // methods of Notebook.
54 56 if (cell instanceof IPython.CodeCell) {
55 57 event.preventDefault();
56 58 cell.clear_output();
57 59 var code = cell.get_code();
58 60 if (that.notebook_load_re.test(code)) {
59 61 var code_parts = code.split(' ');
60 62 if (code_parts.length === 3) {
61 63 that.load_notebook(code_parts[2]);
62 64 };
63 65 } else if (that.notebook_save_re.test(code)) {
64 66 var code_parts = code.split(' ');
65 67 if (code_parts.length === 3) {
66 68 that.save_notebook(code_parts[2]);
67 69 } else {
68 70 that.save_notebook()
69 71 };
70 72 } else {
71 73 var msg_id = that.kernel.execute(cell.get_code());
72 74 that.msg_cell_map[msg_id] = cell.cell_id;
73 75 };
74 76 } else if (cell instanceof IPython.TextCell) {
75 77 event.preventDefault();
76 78 cell.render();
77 79 }
78 80 if (cell_index === (that.ncells()-1)) {
79 81 that.insert_code_cell_after();
80 82 } else {
81 83 that.select(cell_index+1);
82 84 };
83 85 };
84 86 });
85 87 };
86 88
87 89
88 90 // Cell indexing, retrieval, etc.
89 91
90 92
91 93 Notebook.prototype.cell_elements = function () {
92 94 return this.element.children("div.cell");
93 95 }
94 96
95 97
96 98 Notebook.prototype.ncells = function (cell) {
97 99 return this.cell_elements().length;
98 100 }
99 101
100 102
101 103 // TODO: we are often calling cells as cells()[i], which we should optimize
102 104 // to cells(i) or a new method.
103 105 Notebook.prototype.cells = function () {
104 106 return this.cell_elements().toArray().map(function (e) {
105 107 return $(e).data("cell");
106 108 });
107 109 }
108 110
109 111
110 112 Notebook.prototype.find_cell_index = function (cell) {
111 113 var result = null;
112 114 this.cell_elements().filter(function (index) {
113 115 if ($(this).data("cell") === cell) {
114 116 result = index;
115 117 };
116 118 });
117 119 return result;
118 120 };
119 121
120 122
121 123 Notebook.prototype.index_or_selected = function (index) {
122 124 return index || this.selected_index() || 0;
123 125 }
124 126
125 127
126 128 Notebook.prototype.select = function (index) {
127 129 if (index !== undefined && index >= 0 && index < this.ncells()) {
128 130 if (this.selected_index() !== null) {
129 131 this.selected_cell().unselect();
130 132 };
131 133 this.cells()[index].select();
132 134 };
133 135 return this;
134 136 };
135 137
136 138
137 139 Notebook.prototype.select_next = function () {
138 140 var index = this.selected_index();
139 141 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
140 142 this.select(index+1);
141 143 };
142 144 return this;
143 145 };
144 146
145 147
146 148 Notebook.prototype.select_prev = function () {
147 149 var index = this.selected_index();
148 150 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
149 151 this.select(index-1);
150 152 };
151 153 return this;
152 154 };
153 155
154 156
155 157 Notebook.prototype.selected_index = function () {
156 158 var result = null;
157 159 this.cell_elements().filter(function (index) {
158 160 if ($(this).data("cell").selected === true) {
159 161 result = index;
160 162 };
161 163 });
162 164 return result;
163 165 };
164 166
165 167
166 168 Notebook.prototype.cell_for_msg = function (msg_id) {
167 169 var cell_id = this.msg_cell_map[msg_id];
168 170 var result = null;
169 171 this.cell_elements().filter(function (index) {
170 172 cell = $(this).data("cell");
171 173 if (cell.cell_id === cell_id) {
172 174 result = cell;
173 175 };
174 176 });
175 177 return result;
176 178 };
177 179
178 180
179 181 Notebook.prototype.selected_cell = function () {
180 182 return this.cell_elements().eq(this.selected_index()).data("cell");
181 183 }
182 184
183 185
184 186 // Cell insertion, deletion and moving.
185 187
186 188
187 189 Notebook.prototype.delete_cell = function (index) {
188 190 var i = index || this.selected_index();
189 191 if (i !== null && i >= 0 && i < this.ncells()) {
190 192 this.cell_elements().eq(i).remove();
191 193 if (i === (this.ncells())) {
192 194 this.select(i-1);
193 195 } else {
194 196 this.select(i);
195 197 };
196 198 };
197 199 return this;
198 200 };
199 201
200 202
201 203 Notebook.prototype.append_cell = function (cell) {
202 204 this.element.append(cell.element);
203 205 return this;
204 206 };
205 207
206 208
207 209 Notebook.prototype.insert_cell_after = function (cell, index) {
208 210 var ncells = this.ncells();
209 211 if (ncells === 0) {
210 212 this.append_cell(cell);
211 213 return this;
212 214 };
213 215 if (index >= 0 && index < ncells) {
214 216 this.cell_elements().eq(index).after(cell.element);
215 217 };
216 218 return this
217 219 };
218 220
219 221
220 222 Notebook.prototype.insert_cell_before = function (cell, index) {
221 223 var ncells = this.ncells();
222 224 if (ncells === 0) {
223 225 this.append_cell(cell);
224 226 return this;
225 227 };
226 228 if (index >= 0 && index < ncells) {
227 229 this.cell_elements().eq(index).before(cell.element);
228 230 };
229 231 return this;
230 232 };
231 233
232 234
233 235 Notebook.prototype.move_cell_up = function (index) {
234 236 var i = index || this.selected_index();
235 237 if (i !== null && i < this.ncells() && i > 0) {
236 238 var pivot = this.cell_elements().eq(i-1);
237 239 var tomove = this.cell_elements().eq(i);
238 240 if (pivot !== null && tomove !== null) {
239 241 tomove.detach();
240 242 pivot.before(tomove);
241 243 this.select(i-1);
242 244 };
243 245 };
244 246 return this;
245 247 }
246 248
247 249
248 250 Notebook.prototype.move_cell_down = function (index) {
249 251 var i = index || this.selected_index();
250 252 if (i !== null && i < (this.ncells()-1) && i >= 0) {
251 253 var pivot = this.cell_elements().eq(i+1)
252 254 var tomove = this.cell_elements().eq(i)
253 255 if (pivot !== null && tomove !== null) {
254 256 tomove.detach();
255 257 pivot.after(tomove);
256 258 this.select(i+1);
257 259 };
258 260 };
259 261 return this;
260 262 }
261 263
262 264
263 265 Notebook.prototype.sort_cells = function () {
264 266 var ncells = this.ncells();
265 267 var sindex = this.selected_index();
266 268 var swapped;
267 269 do {
268 270 swapped = false
269 271 for (var i=1; i<ncells; i++) {
270 272 current = this.cell_elements().eq(i).data("cell");
271 273 previous = this.cell_elements().eq(i-1).data("cell");
272 274 if (previous.input_prompt_number > current.input_prompt_number) {
273 275 this.move_cell_up(i);
274 276 swapped = true;
275 277 };
276 278 };
277 279 } while (swapped);
278 280 this.select(sindex);
279 281 return this;
280 282 };
281 283
282 284
283 285 Notebook.prototype.insert_code_cell_before = function (index) {
284 286 // TODO: Bounds check for i
285 287 var i = this.index_or_selected(index);
286 288 var cell = new IPython.CodeCell(this);
287 289 cell.set_input_prompt(this.next_prompt_number);
288 290 this.next_prompt_number = this.next_prompt_number + 1;
289 291 this.insert_cell_before(cell, i);
290 292 this.select(this.find_cell_index(cell));
291 293 return this;
292 294 }
293 295
294 296
295 297 Notebook.prototype.insert_code_cell_after = function (index) {
296 298 // TODO: Bounds check for i
297 299 var i = this.index_or_selected(index);
298 300 var cell = new IPython.CodeCell(this);
299 301 cell.set_input_prompt(this.next_prompt_number);
300 302 this.next_prompt_number = this.next_prompt_number + 1;
301 303 this.insert_cell_after(cell, i);
302 304 this.select(this.find_cell_index(cell));
303 305 return this;
304 306 }
305 307
306 308
307 309 Notebook.prototype.insert_text_cell_before = function (index) {
308 310 // TODO: Bounds check for i
309 311 var i = this.index_or_selected(index);
310 312 var cell = new IPython.TextCell(this);
311 313 cell.config_mathjax();
312 314 this.insert_cell_before(cell, i);
313 315 this.select(this.find_cell_index(cell));
314 316 return this;
315 317 }
316 318
317 319
318 320 Notebook.prototype.insert_text_cell_after = function (index) {
319 321 // TODO: Bounds check for i
320 322 var i = this.index_or_selected(index);
321 323 var cell = new IPython.TextCell(this);
322 324 cell.config_mathjax();
323 325 this.insert_cell_after(cell, i);
324 326 this.select(this.find_cell_index(cell));
325 327 return this;
326 328 }
327 329
328 330
329 331 Notebook.prototype.text_to_code = function (index) {
330 332 // TODO: Bounds check for i
331 333 var i = this.index_or_selected(index);
332 334 var source_element = this.cell_elements().eq(i);
333 335 var source_cell = source_element.data("cell");
334 336 if (source_cell instanceof IPython.TextCell) {
335 337 this.insert_code_cell_after(i);
336 338 var target_cell = this.cells()[i+1];
337 339 target_cell.set_code(source_cell.get_text());
338 340 source_element.remove();
339 341 };
340 342 };
341 343
342 344
343 345 Notebook.prototype.code_to_text = function (index) {
344 346 // TODO: Bounds check for i
345 347 var i = this.index_or_selected(index);
346 348 var source_element = this.cell_elements().eq(i);
347 349 var source_cell = source_element.data("cell");
348 350 if (source_cell instanceof IPython.CodeCell) {
349 351 this.insert_text_cell_after(i);
350 352 var target_cell = this.cells()[i+1];
351 353 var text = source_cell.get_code();
352 354 if (text === "") {text = target_cell.placeholder;};
353 355 target_cell.set_text(text);
354 356 source_element.remove();
355 357 target_cell.edit();
356 358 };
357 359 };
358 360
359 361
360 362 // Cell collapsing
361 363
362 364 Notebook.prototype.collapse = function (index) {
363 365 var i = this.index_or_selected(index);
364 366 this.cells()[i].collapse();
365 367 };
366 368
367 369
368 370 Notebook.prototype.expand = function (index) {
369 371 var i = this.index_or_selected(index);
370 372 this.cells()[i].expand();
371 373 };
372 374
373 375
374 376 // Kernel related things
375 377
376 378 Notebook.prototype.start_kernel = function () {
377 379 this.kernel = new IPython.Kernel();
378 380 this.kernel.start_kernel($.proxy(this.kernel_started, this));
379 381 };
380 382
381 383
382 384 Notebook.prototype.handle_shell_reply = function (e) {
383 385 reply = $.parseJSON(e.data);
384 386 var header = reply.header;
385 387 var content = reply.content;
386 388 var msg_type = header.msg_type;
387 389 console.log(reply);
388 390 var cell = this.cell_for_msg(reply.parent_header.msg_id);
389 391 if (msg_type === "execute_reply") {
390 392 cell.set_input_prompt(content.execution_count);
391 393 };
392 394 var payload = content.payload || [];
393 395 this.handle_payload(content.payload);
394 396 };
395 397
396 398
397 399 Notebook.prototype.handle_payload = function (payload) {
398 400 var l = payload.length;
399 401 if (l > 0) {
400 402 IPython.pager.clear();
401 403 IPython.pager.expand();
402 404 };
403 405 for (var i=0; i<l; i++) {
404 406 IPython.pager.append_text(payload[i].text);
405 407 };
406 408 };
407 409
408 410
409 411 Notebook.prototype.handle_iopub_reply = function (e) {
410 412 reply = $.parseJSON(e.data);
411 413 var content = reply.content;
412 414 // console.log(reply);
413 415 var msg_type = reply.header.msg_type;
414 416 var cell = this.cell_for_msg(reply.parent_header.msg_id);
415 417 if (msg_type === "stream") {
416 418 cell.expand();
417 419 cell.append_stream(content.data + "\n");
418 420 } else if (msg_type === "display_data") {
419 421 cell.expand();
420 422 cell.append_display_data(content.data);
421 423 } else if (msg_type === "pyout") {
422 424 cell.expand();
423 425 cell.append_pyout(content.data, content.execution_count)
424 426 } else if (msg_type === "pyerr") {
425 427 cell.expand();
426 428 cell.append_pyerr(content.ename, content.evalue, content.traceback);
427 429 } else if (msg_type === "status") {
428 430 if (content.execution_state === "busy") {
429 431 this.kernel.status_busy();
430 432 } else if (content.execution_state === "idle") {
431 433 this.kernel.status_idle();
432 434 };
433 435 }
434 436 };
435 437
436 438
437 439 Notebook.prototype.kernel_started = function () {
438 440 console.log("Kernel started: ", this.kernel.kernel_id);
439 441 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
440 442 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
441 443 };
442 444
443 445
444 446 // Persistance and loading
445 447
446 448
447 449 Notebook.prototype.fromJSON = function (data) {
448 450 var ncells = this.ncells();
449 451 for (var i=0; i<ncells; i++) {
450 452 // Always delete cell 0 as they get renumbered as they are deleted.
451 453 this.delete_cell(0);
452 454 };
453 455 var new_cells = data.cells;
454 456 ncells = new_cells.length;
455 457 var cell_data = null;
456 458 for (var i=0; i<ncells; i++) {
457 459 cell_data = new_cells[i];
458 460 if (cell_data.cell_type == 'code') {
459 461 this.insert_code_cell_after();
460 462 this.selected_cell().fromJSON(cell_data);
461 463 } else if (cell_data.cell_type === 'text') {
462 464 this.insert_text_cell_after();
463 465 this.selected_cell().fromJSON(cell_data);
464 466 };
465 467 };
466 468 };
467 469
468 470
469 471 Notebook.prototype.toJSON = function () {
470 472 var cells = this.cells();
471 473 var ncells = cells.length;
472 474 cell_array = new Array(ncells);
473 475 for (var i=0; i<ncells; i++) {
474 476 cell_array[i] = cells[i].toJSON();
475 477 };
476 478 json = {
477 479 cells : cell_array
478 480 };
479 481 return json
480 482 };
481 483
482 484
483 485 Notebook.prototype.test_filename = function (filename) {
484 486 if (this.notebook_filename_re.test(filename)) {
485 487 return true;
486 488 } else {
487 489 var bad_filename = $('<div/>');
488 490 bad_filename.html(
489 491 "The filename you entered (" + filename + ") is not valid. Notebook filenames must have the following form: foo.ipynb"
490 492 );
491 493 bad_filename.dialog({title: 'Invalid filename', modal: true});
492 494 return false;
493 495 };
494 496 };
495 497
496 498 Notebook.prototype.save_notebook = function (filename) {
497 499 this.filename = filename || this.filename || '';
498 500 if (this.filename === '') {
499 501 var no_filename = $('<div/>');
500 502 no_filename.html(
501 503 "This notebook has no filename, please specify a filename of the form: foo.ipynb"
502 504 );
503 505 no_filename.dialog({title: 'Missing filename', modal: true});
504 506 return;
505 507 }
506 508 if (!this.test_filename(this.filename)) {return;}
507 509 var thedata = this.toJSON();
508 510 var settings = {
509 511 processData : false,
510 512 cache : false,
511 513 type : "PUT",
512 514 data : JSON.stringify(thedata),
513 515 success : function (data, status, xhr) {console.log(data);}
514 516 };
515 517 $.ajax("/notebooks/" + this.filename, settings);
516 518 };
517 519
518 520
519 521 Notebook.prototype.load_notebook = function (filename) {
520 522 if (!this.test_filename(filename)) {return;}
521 523 var that = this;
522 524 // We do the call with settings so we can set cache to false.
523 525 var settings = {
524 526 processData : false,
525 527 cache : false,
526 528 type : "GET",
527 529 dataType : "json",
528 530 success : function (data, status, xhr) {
529 531 that.fromJSON(data);
530 532 that.filename = filename;
531 533 that.kernel.restart();
532 534 }
533 535 };
534 536 $.ajax("/notebooks/" + filename, settings);
535 537 }
536 538
537 539 IPython.Notebook = Notebook;
538 540
539 541 return IPython;
540 542
541 543 }(IPython));
542 544
General Comments 0
You need to be logged in to leave comments. Login now