##// END OF EJS Templates
Further work on the toolbar UI....
Brian Granger -
Show More
@@ -1,389 +1,393
1 /**
1 /**
2 * Primary styles
2 * Primary styles
3 *
3 *
4 * Author: IPython Development Team
4 * Author: IPython Development Team
5 */
5 */
6
6
7
7
8 body {
8 body {
9 background-color: white;
9 background-color: white;
10 /* This makes sure that the body covers the entire window and needs to
10 /* This makes sure that the body covers the entire window and needs to
11 be in a different element than the display: box in wrapper below */
11 be in a different element than the display: box in wrapper below */
12 position: absolute;
12 position: absolute;
13 left: 0px;
13 left: 0px;
14 right: 0px;
14 right: 0px;
15 top: 0px;
15 top: 0px;
16 bottom: 0px;
16 bottom: 0px;
17 overflow: hidden;
17 overflow: hidden;
18 }
18 }
19
19
20 span#save_widget {
20 span#save_widget {
21 padding: 5px;
21 padding: 5px;
22 margin: 0px 0px 0px 300px;
22 margin: 0px 0px 0px 300px;
23 display:inline-block;
23 display:inline-block;
24 }
24 }
25
25
26 span#notebook_name {
26 span#notebook_name {
27 height: 1em;
27 height: 1em;
28 line-height: 1em;
28 line-height: 1em;
29 padding: 3px;
29 padding: 3px;
30 border: none;
30 border: none;
31 font-size: 146.5%;
31 font-size: 146.5%;
32 }
32 }
33
33
34 #menubar {
34 #menubar {
35 /* Initially hidden to prevent FLOUC */
35 /* Initially hidden to prevent FLOUC */
36 display: none;
36 display: none;
37 }
37 }
38
38
39 .ui-menubar-item .ui-button .ui-button-text {
39 .ui-menubar-item .ui-button .ui-button-text {
40 padding: 0.4em 1.0em;
40 padding: 0.4em 1.0em;
41 font-size: 100%;
41 font-size: 100%;
42 }
42 }
43
43
44 .ui-menu {
44 .ui-menu {
45 -moz-box-shadow: 0px 6px 10px -1px #adadad;
45 -moz-box-shadow: 0px 6px 10px -1px #adadad;
46 -webkit-box-shadow: 0px 6px 10px -1px #adadad;
46 -webkit-box-shadow: 0px 6px 10px -1px #adadad;
47 box-shadow: 0px 6px 10px -1px #adadad;
47 box-shadow: 0px 6px 10px -1px #adadad;
48 }
48 }
49
49
50 .ui-menu .ui-menu-item a {
50 .ui-menu .ui-menu-item a {
51 padding: 2px 1.6em;
51 padding: 2px 1.6em;
52 }
52 }
53
53
54 .ui-menu hr {
54 .ui-menu hr {
55 margin: 0.3em 0;
55 margin: 0.3em 0;
56 }
56 }
57
57
58 #toolbar {
58 #toolbar {
59 /* Initially hidden to prevent FLOUC */
59 /* Initially hidden to prevent FLOUC */
60 display: none;
60 display: none;
61 padding: 3px 15px;
61 padding: 3px 15px;
62 }
62 }
63
63
64 #cell_type {
65 font-size: 85%;
66 }
67
64 span#quick_help_area {
68 span#quick_help_area {
65 position: static;
69 position: static;
66 padding: 5px 0px;
70 padding: 5px 0px;
67 margin: 0px 0px 0px 0px;
71 margin: 0px 0px 0px 0px;
68 }
72 }
69
73
70 span#kernel_status {
74 span#kernel_status {
71 position: absolute;
75 position: absolute;
72 padding: 8px 5px 5px 5px;
76 padding: 8px 5px 5px 5px;
73 right: 10px;
77 right: 10px;
74 font-weight: bold;
78 font-weight: bold;
75 }
79 }
76
80
77
81
78 .status_idle {
82 .status_idle {
79 color: gray;
83 color: gray;
80 visibility: hidden;
84 visibility: hidden;
81 }
85 }
82
86
83 .status_busy {
87 .status_busy {
84 color: red;
88 color: red;
85 }
89 }
86
90
87 .status_restarting {
91 .status_restarting {
88 color: black;
92 color: black;
89 }
93 }
90
94
91 #kernel_persist {
95 #kernel_persist {
92 float: right;
96 float: right;
93 }
97 }
94
98
95 .help_string {
99 .help_string {
96 float: right;
100 float: right;
97 width: 170px;
101 width: 170px;
98 padding: 0px 5px;
102 padding: 0px 5px;
99 text-align: left;
103 text-align: left;
100 font-size: 85%;
104 font-size: 85%;
101 }
105 }
102
106
103 .help_string_label {
107 .help_string_label {
104 float: right;
108 float: right;
105 font-size: 85%;
109 font-size: 85%;
106 }
110 }
107
111
108 div#notebook_panel {
112 div#notebook_panel {
109 margin: 0px 0px 0px 0px;
113 margin: 0px 0px 0px 0px;
110 padding: 0px;
114 padding: 0px;
111 }
115 }
112
116
113 div#notebook {
117 div#notebook {
114 overflow-y: scroll;
118 overflow-y: scroll;
115 overflow-x: auto;
119 overflow-x: auto;
116 width: 100%;
120 width: 100%;
117 /* This spaces the cell away from the edge of the notebook area */
121 /* This spaces the cell away from the edge of the notebook area */
118 padding: 5px 5px 15px 5px;
122 padding: 5px 5px 15px 5px;
119 margin: 0px
123 margin: 0px
120 background-color: white;
124 background-color: white;
121 }
125 }
122
126
123 div#pager_splitter {
127 div#pager_splitter {
124 height: 8px;
128 height: 8px;
125 }
129 }
126
130
127 div#pager {
131 div#pager {
128 padding: 15px;
132 padding: 15px;
129 overflow: auto;
133 overflow: auto;
130 display: none;
134 display: none;
131 }
135 }
132
136
133 div.cell {
137 div.cell {
134 width: 100%;
138 width: 100%;
135 padding: 5px 5px 5px 0px;
139 padding: 5px 5px 5px 0px;
136 /* This acts as a spacer between cells, that is outside the border */
140 /* This acts as a spacer between cells, that is outside the border */
137 margin: 2px 0px 2px 0px;
141 margin: 2px 0px 2px 0px;
138 }
142 }
139
143
140 div.code_cell {
144 div.code_cell {
141 background-color: white;
145 background-color: white;
142 }
146 }
143 /* any special styling for code cells that are currently running goes here */
147 /* any special styling for code cells that are currently running goes here */
144 div.code_cell.running {
148 div.code_cell.running {
145 }
149 }
146
150
147 div.prompt {
151 div.prompt {
148 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
152 /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */
149 width: 11ex;
153 width: 11ex;
150 /* This 0.4em is tuned to match the padding on the CodeMirror editor. */
154 /* This 0.4em is tuned to match the padding on the CodeMirror editor. */
151 padding: 0.4em;
155 padding: 0.4em;
152 margin: 0px;
156 margin: 0px;
153 font-family: monospace;
157 font-family: monospace;
154 text-align:right;
158 text-align:right;
155 }
159 }
156
160
157 div.input {
161 div.input {
158 page-break-inside: avoid;
162 page-break-inside: avoid;
159 }
163 }
160
164
161 /* input_area and input_prompt must match in top border and margin for alignment */
165 /* input_area and input_prompt must match in top border and margin for alignment */
162 div.input_area {
166 div.input_area {
163 color: black;
167 color: black;
164 border: 1px solid #ddd;
168 border: 1px solid #ddd;
165 border-radius: 3px;
169 border-radius: 3px;
166 background: #f7f7f7;
170 background: #f7f7f7;
167 }
171 }
168
172
169 div.input_prompt {
173 div.input_prompt {
170 color: navy;
174 color: navy;
171 border-top: 1px solid transparent;
175 border-top: 1px solid transparent;
172 }
176 }
173
177
174 div.output {
178 div.output {
175 /* This is a spacer between the input and output of each cell */
179 /* This is a spacer between the input and output of each cell */
176 margin-top: 5px;
180 margin-top: 5px;
177 }
181 }
178
182
179 div.output_prompt {
183 div.output_prompt {
180 color: darkred;
184 color: darkred;
181 }
185 }
182
186
183 /* This class is the outer container of all output sections. */
187 /* This class is the outer container of all output sections. */
184 div.output_area {
188 div.output_area {
185 padding: 0px;
189 padding: 0px;
186 page-break-inside: avoid;
190 page-break-inside: avoid;
187 }
191 }
188
192
189 /* This class is for the output subarea inside the output_area and after
193 /* This class is for the output subarea inside the output_area and after
190 the prompt div. */
194 the prompt div. */
191 div.output_subarea {
195 div.output_subarea {
192 padding: 0.4em 6.1em 0.4em 0.4em;
196 padding: 0.4em 6.1em 0.4em 0.4em;
193 }
197 }
194
198
195 /* The rest of the output_* classes are for special styling of the different
199 /* The rest of the output_* classes are for special styling of the different
196 output types */
200 output types */
197
201
198 /* all text output has this class: */
202 /* all text output has this class: */
199 div.output_text {
203 div.output_text {
200 text-align: left;
204 text-align: left;
201 color: black;
205 color: black;
202 font-family: monospace;
206 font-family: monospace;
203 }
207 }
204
208
205 /* stdout/stderr are 'text' as well as 'stream', but pyout/pyerr are *not* streams */
209 /* stdout/stderr are 'text' as well as 'stream', but pyout/pyerr are *not* streams */
206 div.output_stream {
210 div.output_stream {
207 padding-top: 0.0em;
211 padding-top: 0.0em;
208 padding-bottom: 0.0em;
212 padding-bottom: 0.0em;
209 }
213 }
210 div.output_stdout {
214 div.output_stdout {
211 }
215 }
212 div.output_stderr {
216 div.output_stderr {
213 background: #fdd; /* very light red background for stderr */
217 background: #fdd; /* very light red background for stderr */
214 }
218 }
215
219
216 div.output_latex {
220 div.output_latex {
217 text-align: left;
221 text-align: left;
218 color: black;
222 color: black;
219 }
223 }
220
224
221 div.output_html {
225 div.output_html {
222 }
226 }
223
227
224 div.output_png {
228 div.output_png {
225 }
229 }
226
230
227 div.output_jpeg {
231 div.output_jpeg {
228 }
232 }
229
233
230 div.text_cell {
234 div.text_cell {
231 background-color: white;
235 background-color: white;
232 padding: 5px 5px 5px 5px;
236 padding: 5px 5px 5px 5px;
233 }
237 }
234
238
235 div.text_cell_input {
239 div.text_cell_input {
236 color: black;
240 color: black;
237 border: 1px solid #ddd;
241 border: 1px solid #ddd;
238 border-radius: 3px;
242 border-radius: 3px;
239 background: #f7f7f7;
243 background: #f7f7f7;
240 }
244 }
241
245
242 div.text_cell_render {
246 div.text_cell_render {
243 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
247 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
244 outline: none;
248 outline: none;
245 resize: none;
249 resize: none;
246 width: inherit;
250 width: inherit;
247 border-style: none;
251 border-style: none;
248 padding: 5px;
252 padding: 5px;
249 color: black;
253 color: black;
250 }
254 }
251
255
252 .CodeMirror {
256 .CodeMirror {
253 line-height: 1.231; /* Changed from 1em to our global default */
257 line-height: 1.231; /* Changed from 1em to our global default */
254 }
258 }
255
259
256 .CodeMirror-scroll {
260 .CodeMirror-scroll {
257 height: auto; /* Changed to auto to autogrow */
261 height: auto; /* Changed to auto to autogrow */
258 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
262 /* The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/
259 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
263 /* We have found that if it is visible, vertical scrollbars appear with font size changes.*/
260 overflow-y: hidden;
264 overflow-y: hidden;
261 overflow-x: auto; /* Changed from auto to remove scrollbar */
265 overflow-x: auto; /* Changed from auto to remove scrollbar */
262 }
266 }
263
267
264 /* CSS font colors for translated ANSI colors. */
268 /* CSS font colors for translated ANSI colors. */
265
269
266
270
267 .ansiblack {color: black;}
271 .ansiblack {color: black;}
268 .ansired {color: darkred;}
272 .ansired {color: darkred;}
269 .ansigreen {color: darkgreen;}
273 .ansigreen {color: darkgreen;}
270 .ansiyellow {color: brown;}
274 .ansiyellow {color: brown;}
271 .ansiblue {color: darkblue;}
275 .ansiblue {color: darkblue;}
272 .ansipurple {color: darkviolet;}
276 .ansipurple {color: darkviolet;}
273 .ansicyan {color: steelblue;}
277 .ansicyan {color: steelblue;}
274 .ansigrey {color: grey;}
278 .ansigrey {color: grey;}
275 .ansibold {font-weight: bold;}
279 .ansibold {font-weight: bold;}
276
280
277 .completions , .tooltip {
281 .completions , .tooltip {
278 position: absolute;
282 position: absolute;
279 z-index: 10;
283 z-index: 10;
280 overflow: auto;
284 overflow: auto;
281 border: 1px solid black;
285 border: 1px solid black;
282 }
286 }
283
287
284 .completions select {
288 .completions select {
285 background: white;
289 background: white;
286 outline: none;
290 outline: none;
287 border: none;
291 border: none;
288 padding: 0px;
292 padding: 0px;
289 margin: 0px;
293 margin: 0px;
290 font-family: monospace;
294 font-family: monospace;
291 }
295 }
292
296
293 @-moz-keyframes fadeIn {
297 @-moz-keyframes fadeIn {
294 from {opacity:0;}
298 from {opacity:0;}
295 to {opacity:1;}
299 to {opacity:1;}
296 }
300 }
297
301
298 @-webkit-keyframes fadeIn {
302 @-webkit-keyframes fadeIn {
299 from {opacity:0;}
303 from {opacity:0;}
300 to {opacity:1;}
304 to {opacity:1;}
301 }
305 }
302
306
303 @keyframes fadeIn {
307 @keyframes fadeIn {
304 from {opacity:0;}
308 from {opacity:0;}
305 to {opacity:1;}
309 to {opacity:1;}
306 }
310 }
307
311
308 /*"close" "expand" and "Open in pager button" of
312 /*"close" "expand" and "Open in pager button" of
309 /* the tooltip*/
313 /* the tooltip*/
310 .tooltip a {
314 .tooltip a {
311 float:right;
315 float:right;
312 }
316 }
313
317
314 /*properties of tooltip after "expand"*/
318 /*properties of tooltip after "expand"*/
315 .bigtooltip {
319 .bigtooltip {
316 height:30%;
320 height:30%;
317 }
321 }
318
322
319 /*properties of tooltip before "expand"*/
323 /*properties of tooltip before "expand"*/
320 .smalltooltip {
324 .smalltooltip {
321 text-overflow: ellipsis;
325 text-overflow: ellipsis;
322 overflow: hidden;
326 overflow: hidden;
323 height:15%;
327 height:15%;
324 }
328 }
325
329
326 .tooltip {
330 .tooltip {
327 /*transition when "expand"ing tooltip */
331 /*transition when "expand"ing tooltip */
328 -webkit-transition-property: height;
332 -webkit-transition-property: height;
329 -webkit-transition-duration: 1s;
333 -webkit-transition-duration: 1s;
330 -moz-transition-property: height;
334 -moz-transition-property: height;
331 -moz-transition-duration: 1s;
335 -moz-transition-duration: 1s;
332 transition-property: height;
336 transition-property: height;
333 transition-duration: 1s;
337 transition-duration: 1s;
334 max-width:700px;
338 max-width:700px;
335 border-radius: 0px 10px 10px 10px;
339 border-radius: 0px 10px 10px 10px;
336 box-shadow: 3px 3px 5px #999;
340 box-shadow: 3px 3px 5px #999;
337 /*fade-in animation when inserted*/
341 /*fade-in animation when inserted*/
338 -webkit-animation: fadeIn 200ms;
342 -webkit-animation: fadeIn 200ms;
339 -moz-animation: fadeIn 200ms;
343 -moz-animation: fadeIn 200ms;
340 animation: fadeIn 200ms;
344 animation: fadeIn 200ms;
341 vertical-align: middle;
345 vertical-align: middle;
342 background: #FDFDD8;
346 background: #FDFDD8;
343 outline: none;
347 outline: none;
344 padding: 3px;
348 padding: 3px;
345 margin: 0px;
349 margin: 0px;
346 font-family: monospace;
350 font-family: monospace;
347 min-height:50px;
351 min-height:50px;
348 }
352 }
349
353
350 /*fixed part of the completion*/
354 /*fixed part of the completion*/
351 .completions p b {
355 .completions p b {
352 font-weight:bold;
356 font-weight:bold;
353 }
357 }
354
358
355 .completions p {
359 .completions p {
356 background: #DDF;
360 background: #DDF;
357 /*outline: none;
361 /*outline: none;
358 padding: 0px;*/
362 padding: 0px;*/
359 border-bottom: black solid 1px;
363 border-bottom: black solid 1px;
360 padding: 1px;
364 padding: 1px;
361 font-family: monospace;
365 font-family: monospace;
362 }
366 }
363
367
364 pre.dialog {
368 pre.dialog {
365 background-color: #f7f7f7;
369 background-color: #f7f7f7;
366 border: 1px solid #ddd;
370 border: 1px solid #ddd;
367 border-radius: 3px;
371 border-radius: 3px;
368 padding: 0.4em;
372 padding: 0.4em;
369 padding-left: 2em;
373 padding-left: 2em;
370 }
374 }
371
375
372 p.dialog {
376 p.dialog {
373 padding : 0.2em;
377 padding : 0.2em;
374 }
378 }
375
379
376 .shortcut_key {
380 .shortcut_key {
377 display: inline-block;
381 display: inline-block;
378 width: 15ex;
382 width: 15ex;
379 text-align: right;
383 text-align: right;
380 font-family: monospace;
384 font-family: monospace;
381 }
385 }
382
386
383 .shortcut_descr {
387 .shortcut_descr {
384 }
388 }
385
389
386 /* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems
390 /* Word-wrap output correctly. This is the CSS3 spelling, though Firefox seems
387 to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do.
391 to not honor it correctly. Webkit browsers (Chrome, rekonq, Safari) do.
388 */
392 */
389 pre, code, kbd, samp { white-space: pre-wrap; }
393 pre, code, kbd, samp { white-space: pre-wrap; }
@@ -1,49 +1,59
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 // Layout
9 // Layout
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var LayoutManager = function () {
14 var LayoutManager = function () {
15 this.bind_events();
15 this.bind_events();
16 };
16 };
17
17
18
18
19 LayoutManager.prototype.bind_events = function () {
19 LayoutManager.prototype.bind_events = function () {
20 $(window).resize($.proxy(this.do_resize,this));
20 $(window).resize($.proxy(this.do_resize,this));
21 };
21 };
22
22
23
23
24 LayoutManager.prototype.do_resize = function () {
24 LayoutManager.prototype.do_resize = function () {
25 var win = $(window);
25 var win = $(window);
26 var w = win.width();
26 var w = win.width();
27 var h = win.height();
27 var h = win.height();
28 var header_height = $('div#header').outerHeight(true);
28 var header_height;
29 if ($('div#header').css('display') === 'none') {
30 header_height = 0;
31 } else {
32 header_height = $('div#header').outerHeight(true);
33 }
29 var menubar_height = $('div#menubar').outerHeight(true);
34 var menubar_height = $('div#menubar').outerHeight(true);
30 var toolbar_height = $('div#toolbar').outerHeight(true);
35 var toolbar_height;
36 if ($('div#toolbar').css('display') === 'none') {
37 toolbar_height = 0;
38 } else {
39 toolbar_height = $('div#toolbar').outerHeight(true);
40 }
31 var app_height = h-header_height-menubar_height-toolbar_height-2; // content height
41 var app_height = h-header_height-menubar_height-toolbar_height-2; // content height
32
42
33 $('div#main_app').height(app_height + 2); // content+padding+border height
43 $('div#main_app').height(app_height + 2); // content+padding+border height
34
44
35 var pager_height = IPython.pager.percentage_height*app_height;
45 var pager_height = IPython.pager.percentage_height*app_height;
36 var pager_splitter_height = $('div#pager_splitter').outerHeight(true);
46 var pager_splitter_height = $('div#pager_splitter').outerHeight(true);
37 $('div#pager').height(pager_height);
47 $('div#pager').height(pager_height);
38 if (IPython.pager.expanded) {
48 if (IPython.pager.expanded) {
39 $('div#notebook').height(app_height-pager_height-pager_splitter_height);
49 $('div#notebook').height(app_height-pager_height-pager_splitter_height);
40 } else {
50 } else {
41 $('div#notebook').height(app_height-pager_splitter_height);
51 $('div#notebook').height(app_height-pager_splitter_height);
42 }
52 }
43 };
53 };
44
54
45 IPython.LayoutManager = LayoutManager;
55 IPython.LayoutManager = LayoutManager;
46
56
47 return IPython;
57 return IPython;
48
58
49 }(IPython));
59 }(IPython));
@@ -1,148 +1,156
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 // MenuBar
9 // MenuBar
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var MenuBar = function (selector) {
14 var MenuBar = function (selector) {
15 this.selector = selector;
15 this.selector = selector;
16 if (this.selector !== undefined) {
16 if (this.selector !== undefined) {
17 this.element = $(selector);
17 this.element = $(selector);
18 this.style();
18 this.style();
19 this.bind_events();
19 this.bind_events();
20 }
20 }
21 };
21 };
22
22
23
23
24 MenuBar.prototype.style = function () {
24 MenuBar.prototype.style = function () {
25 $('ul#menus').menubar({
25 $('ul#menus').menubar({
26 select : function (event, ui) {
26 select : function (event, ui) {
27 // The selected cell loses focus when the menu is entered, so we
27 // The selected cell loses focus when the menu is entered, so we
28 // re-select it upon selection.
28 // re-select it upon selection.
29 var i = IPython.notebook.get_selected_index();
29 var i = IPython.notebook.get_selected_index();
30 IPython.notebook.select(i);
30 IPython.notebook.select(i);
31 }
31 }
32 });
32 });
33 };
33 };
34
34
35
35
36 MenuBar.prototype.bind_events = function () {
36 MenuBar.prototype.bind_events = function () {
37 // File
37 // File
38 this.element.find('#new_notebook').click(function () {
38 this.element.find('#new_notebook').click(function () {
39 window.open($('body').data('baseProjectUrl')+'new');
39 window.open($('body').data('baseProjectUrl')+'new');
40 });
40 });
41 this.element.find('#open_notebook').click(function () {
41 this.element.find('#open_notebook').click(function () {
42 window.open($('body').data('baseProjectUrl'));
42 window.open($('body').data('baseProjectUrl'));
43 });
43 });
44 this.element.find('#rename_notebook').click(function () {
44 this.element.find('#rename_notebook').click(function () {
45 IPython.save_widget.rename_notebook();
45 IPython.save_widget.rename_notebook();
46 });
46 });
47 this.element.find('#copy_notebook').click(function () {
47 this.element.find('#copy_notebook').click(function () {
48 var notebook_id = IPython.save_widget.get_notebook_id();
48 var notebook_id = IPython.save_widget.get_notebook_id();
49 var url = $('body').data('baseProjectUrl') + notebook_id + '/copy';
49 var url = $('body').data('baseProjectUrl') + notebook_id + '/copy';
50 window.open(url,'_newtab');
50 window.open(url,'_newtab');
51 });
51 });
52 this.element.find('#save_notebook').click(function () {
52 this.element.find('#save_notebook').click(function () {
53 IPython.save_widget.save_notebook();
53 IPython.save_widget.save_notebook();
54 });
54 });
55 this.element.find('#download_ipynb').click(function () {
55 this.element.find('#download_ipynb').click(function () {
56 var notebook_id = IPython.save_widget.get_notebook_id();
56 var notebook_id = IPython.save_widget.get_notebook_id();
57 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
57 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
58 notebook_id + '?format=json';
58 notebook_id + '?format=json';
59 window.open(url,'_newtab');
59 window.open(url,'_newtab');
60 });
60 });
61 this.element.find('#download_py').click(function () {
61 this.element.find('#download_py').click(function () {
62 var notebook_id = IPython.save_widget.get_notebook_id();
62 var notebook_id = IPython.save_widget.get_notebook_id();
63 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
63 var url = $('body').data('baseProjectUrl') + 'notebooks/' +
64 notebook_id + '?format=py';
64 notebook_id + '?format=py';
65 window.open(url,'_newtab');
65 window.open(url,'_newtab');
66 });
66 });
67 this.element.find('button#print_notebook').click(function () {
67 this.element.find('button#print_notebook').click(function () {
68 IPython.print_widget.print_notebook();
68 IPython.print_widget.print_notebook();
69 });
69 });
70 // Edit
70 // Edit
71 this.element.find('#cut_cell').click(function () {
71 this.element.find('#cut_cell').click(function () {
72 IPython.notebook.cut_cell();
72 IPython.notebook.cut_cell();
73 });
73 });
74 this.element.find('#copy_cell').click(function () {
74 this.element.find('#copy_cell').click(function () {
75 IPython.notebook.copy_cell();
75 IPython.notebook.copy_cell();
76 });
76 });
77 this.element.find('#delete_cell').click(function () {
77 this.element.find('#delete_cell').click(function () {
78 IPython.notebook.delete_cell();
78 IPython.notebook.delete_cell();
79 });
79 });
80 this.element.find('#split_cell').click(function () {
80 this.element.find('#split_cell').click(function () {
81 IPython.notebook.split_cell();
81 IPython.notebook.split_cell();
82 });
82 });
83 this.element.find('#merge_cell_above').click(function () {
83 this.element.find('#merge_cell_above').click(function () {
84 IPython.notebook.merge_cell_above();
84 IPython.notebook.merge_cell_above();
85 });
85 });
86 this.element.find('#merge_cell_below').click(function () {
86 this.element.find('#merge_cell_below').click(function () {
87 IPython.notebook.merge_cell_below();
87 IPython.notebook.merge_cell_below();
88 });
88 });
89 this.element.find('#move_cell_up').click(function () {
89 this.element.find('#move_cell_up').click(function () {
90 IPython.notebook.move_cell_up();
90 IPython.notebook.move_cell_up();
91 });
91 });
92 this.element.find('#move_cell_down').click(function () {
92 this.element.find('#move_cell_down').click(function () {
93 IPython.notebook.move_cell_down();
93 IPython.notebook.move_cell_down();
94 });
94 });
95 this.element.find('#select_previous').click(function () {
95 this.element.find('#select_previous').click(function () {
96 IPython.notebook.select_prev();
96 IPython.notebook.select_prev();
97 });
97 });
98 this.element.find('#select_next').click(function () {
98 this.element.find('#select_next').click(function () {
99 IPython.notebook.select_next();
99 IPython.notebook.select_next();
100 });
100 });
101 // View
102 this.element.find('#toggle_header').click(function () {
103 $('div#header').toggle();
104 IPython.layout_manager.do_resize();
105 });
106 this.element.find('#toggle_toolbar').click(function () {
107 IPython.toolbar.toggle();
108 });
101 // Insert
109 // Insert
102 this.element.find('#insert_cell_above').click(function () {
110 this.element.find('#insert_cell_above').click(function () {
103 IPython.notebook.insert_cell_above('code');
111 IPython.notebook.insert_cell_above('code');
104 });
112 });
105 this.element.find('#insert_cell_below').click(function () {
113 this.element.find('#insert_cell_below').click(function () {
106 IPython.notebook.insert_cell_below('code');
114 IPython.notebook.insert_cell_below('code');
107 });
115 });
108 // Cell
116 // Cell
109 this.element.find('#run_cell').click(function () {
117 this.element.find('#run_cell').click(function () {
110 IPython.notebook.execute_selected_cell();
118 IPython.notebook.execute_selected_cell();
111 });
119 });
112 this.element.find('#run_cell_in_place').click(function () {
120 this.element.find('#run_cell_in_place').click(function () {
113 IPython.notebook.execute_selected_cell({terminal:true});
121 IPython.notebook.execute_selected_cell({terminal:true});
114 });
122 });
115 this.element.find('#run_all_cells').click(function () {
123 this.element.find('#run_all_cells').click(function () {
116 IPython.notebook.execute_all_cells();
124 IPython.notebook.execute_all_cells();
117 });
125 });
118 this.element.find('#to_code').click(function () {
126 this.element.find('#to_code').click(function () {
119 IPython.notebook.to_code();
127 IPython.notebook.to_code();
120 });
128 });
121 this.element.find('#to_markdown').click(function () {
129 this.element.find('#to_markdown').click(function () {
122 IPython.notebook.to_markdown();
130 IPython.notebook.to_markdown();
123 });
131 });
124 this.element.find('#toggle_output').click(function () {
132 this.element.find('#toggle_output').click(function () {
125 IPython.notebook.toggle_output();
133 IPython.notebook.toggle_output();
126 });
134 });
127 this.element.find('#clear_all_output').click(function () {
135 this.element.find('#clear_all_output').click(function () {
128 IPython.notebook.clear_all_output();
136 IPython.notebook.clear_all_output();
129 });
137 });
130 // Kernel
138 // Kernel
131 this.element.find('#int_kernel').click(function () {
139 this.element.find('#int_kernel').click(function () {
132 IPython.notebook.kernel.interrupt();
140 IPython.notebook.kernel.interrupt();
133 });
141 });
134 this.element.find('#restart_kernel').click(function () {
142 this.element.find('#restart_kernel').click(function () {
135 IPython.notebook.restart_kernel();
143 IPython.notebook.restart_kernel();
136 });
144 });
137 // Help
145 // Help
138 this.element.find('#keyboard_shortcuts').click(function () {
146 this.element.find('#keyboard_shortcuts').click(function () {
139 IPython.quick_help.show_keyboard_shortcuts();
147 IPython.quick_help.show_keyboard_shortcuts();
140 });
148 });
141 };
149 };
142
150
143
151
144 IPython.MenuBar = MenuBar;
152 IPython.MenuBar = MenuBar;
145
153
146 return IPython;
154 return IPython;
147
155
148 }(IPython));
156 }(IPython));
@@ -1,1163 +1,1165
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.read_only = IPython.read_only;
17 this.read_only = IPython.read_only;
18 this.element = $(selector);
18 this.element = $(selector);
19 this.element.scroll();
19 this.element.scroll();
20 this.element.data("notebook", this);
20 this.element.data("notebook", this);
21 this.next_prompt_number = 1;
21 this.next_prompt_number = 1;
22 this.kernel = null;
22 this.kernel = null;
23 this.clipboard = null;
23 this.clipboard = null;
24 this.paste_enabled = false;
24 this.paste_enabled = false;
25 this.dirty = false;
25 this.dirty = false;
26 this.msg_cell_map = {};
26 this.msg_cell_map = {};
27 this.metadata = {};
27 this.metadata = {};
28 this.control_key_active = false;
28 this.control_key_active = false;
29 this.style();
29 this.style();
30 this.create_elements();
30 this.create_elements();
31 this.bind_events();
31 this.bind_events();
32 this.set_tooltipontab(true);
32 this.set_tooltipontab(true);
33 this.set_smartcompleter(true);
33 this.set_smartcompleter(true);
34 this.set_timebeforetooltip(1200);
34 this.set_timebeforetooltip(1200);
35 };
35 };
36
36
37
37
38 Notebook.prototype.style = function () {
38 Notebook.prototype.style = function () {
39 $('div#notebook').addClass('border-box-sizing');
39 $('div#notebook').addClass('border-box-sizing');
40 };
40 };
41
41
42
42
43 Notebook.prototype.create_elements = function () {
43 Notebook.prototype.create_elements = function () {
44 // We add this end_space div to the end of the notebook div to:
44 // We add this end_space div to the end of the notebook div to:
45 // i) provide a margin between the last cell and the end of the notebook
45 // i) provide a margin between the last cell and the end of the notebook
46 // ii) to prevent the div from scrolling up when the last cell is being
46 // ii) to prevent the div from scrolling up when the last cell is being
47 // edited, but is too low on the page, which browsers will do automatically.
47 // edited, but is too low on the page, which browsers will do automatically.
48 var that = this;
48 var that = this;
49 var end_space = $('<div/>').addClass('end_space').height("30%");
49 var end_space = $('<div/>').addClass('end_space').height("30%");
50 end_space.dblclick(function (e) {
50 end_space.dblclick(function (e) {
51 if (that.read_only) return;
51 if (that.read_only) return;
52 var ncells = that.ncells();
52 var ncells = that.ncells();
53 that.insert_cell_below('code',ncells-1);
53 that.insert_cell_below('code',ncells-1);
54 });
54 });
55 this.element.append(end_space);
55 this.element.append(end_space);
56 $('div#notebook').addClass('border-box-sizing');
56 $('div#notebook').addClass('border-box-sizing');
57 };
57 };
58
58
59
59
60 Notebook.prototype.bind_events = function () {
60 Notebook.prototype.bind_events = function () {
61 var that = this;
61 var that = this;
62 $(document).keydown(function (event) {
62 $(document).keydown(function (event) {
63 // console.log(event);
63 // console.log(event);
64 if (that.read_only) return true;
64 if (that.read_only) return true;
65 if (event.which === 27) {
65 if (event.which === 27) {
66 // Intercept escape at highest level to avoid closing
66 // Intercept escape at highest level to avoid closing
67 // websocket connection with firefox
67 // websocket connection with firefox
68 event.preventDefault();
68 event.preventDefault();
69 }
69 }
70 if (event.which === 38 && !event.shiftKey) {
70 if (event.which === 38 && !event.shiftKey) {
71 var cell = that.get_selected_cell();
71 var cell = that.get_selected_cell();
72 if (cell.at_top()) {
72 if (cell.at_top()) {
73 event.preventDefault();
73 event.preventDefault();
74 that.select_prev();
74 that.select_prev();
75 };
75 };
76 } else if (event.which === 40 && !event.shiftKey) {
76 } else if (event.which === 40 && !event.shiftKey) {
77 var cell = that.get_selected_cell();
77 var cell = that.get_selected_cell();
78 if (cell.at_bottom()) {
78 if (cell.at_bottom()) {
79 event.preventDefault();
79 event.preventDefault();
80 that.select_next();
80 that.select_next();
81 };
81 };
82 } else if (event.which === 13 && event.shiftKey) {
82 } else if (event.which === 13 && event.shiftKey) {
83 that.execute_selected_cell();
83 that.execute_selected_cell();
84 return false;
84 return false;
85 } else if (event.which === 13 && event.ctrlKey) {
85 } else if (event.which === 13 && event.ctrlKey) {
86 that.execute_selected_cell({terminal:true});
86 that.execute_selected_cell({terminal:true});
87 return false;
87 return false;
88 } else if (event.which === 77 && event.ctrlKey) {
88 } else if (event.which === 77 && event.ctrlKey) {
89 that.control_key_active = true;
89 that.control_key_active = true;
90 return false;
90 return false;
91 } else if (event.which === 88 && that.control_key_active) {
91 } else if (event.which === 88 && that.control_key_active) {
92 // Cut selected cell = x
92 // Cut selected cell = x
93 that.cut_cell();
93 that.cut_cell();
94 that.control_key_active = false;
94 that.control_key_active = false;
95 return false;
95 return false;
96 } else if (event.which === 67 && that.control_key_active) {
96 } else if (event.which === 67 && that.control_key_active) {
97 // Copy selected cell = c
97 // Copy selected cell = c
98 that.copy_cell();
98 that.copy_cell();
99 that.control_key_active = false;
99 that.control_key_active = false;
100 return false;
100 return false;
101 } else if (event.which === 86 && that.control_key_active) {
101 } else if (event.which === 86 && that.control_key_active) {
102 // Paste selected cell = v
102 // Paste selected cell = v
103 that.paste_cell();
103 that.paste_cell();
104 that.control_key_active = false;
104 that.control_key_active = false;
105 return false;
105 return false;
106 } else if (event.which === 68 && that.control_key_active) {
106 } else if (event.which === 68 && that.control_key_active) {
107 // Delete selected cell = d
107 // Delete selected cell = d
108 that.delete_cell();
108 that.delete_cell();
109 that.control_key_active = false;
109 that.control_key_active = false;
110 return false;
110 return false;
111 } else if (event.which === 65 && that.control_key_active) {
111 } else if (event.which === 65 && that.control_key_active) {
112 // Insert code cell above selected = a
112 // Insert code cell above selected = a
113 that.insert_cell_above('code');
113 that.insert_cell_above('code');
114 that.control_key_active = false;
114 that.control_key_active = false;
115 return false;
115 return false;
116 } else if (event.which === 66 && that.control_key_active) {
116 } else if (event.which === 66 && that.control_key_active) {
117 // Insert code cell below selected = b
117 // Insert code cell below selected = b
118 that.insert_cell_below('code');
118 that.insert_cell_below('code');
119 that.control_key_active = false;
119 that.control_key_active = false;
120 return false;
120 return false;
121 } else if (event.which === 89 && that.control_key_active) {
121 } else if (event.which === 89 && that.control_key_active) {
122 // To code = y
122 // To code = y
123 that.to_code();
123 that.to_code();
124 that.control_key_active = false;
124 that.control_key_active = false;
125 return false;
125 return false;
126 } else if (event.which === 77 && that.control_key_active) {
126 } else if (event.which === 77 && that.control_key_active) {
127 // To markdown = m
127 // To markdown = m
128 that.to_markdown();
128 that.to_markdown();
129 that.control_key_active = false;
129 that.control_key_active = false;
130 return false;
130 return false;
131 } else if (event.which === 84 && that.control_key_active) {
131 } else if (event.which === 84 && that.control_key_active) {
132 // Toggle output = t
132 // Toggle output = t
133 that.toggle_output();
133 that.toggle_output();
134 that.control_key_active = false;
134 that.control_key_active = false;
135 return false;
135 return false;
136 } else if (event.which === 83 && that.control_key_active) {
136 } else if (event.which === 83 && that.control_key_active) {
137 // Save notebook = s
137 // Save notebook = s
138 IPython.save_widget.save_notebook();
138 IPython.save_widget.save_notebook();
139 that.control_key_active = false;
139 that.control_key_active = false;
140 return false;
140 return false;
141 } else if (event.which === 74 && that.control_key_active) {
141 } else if (event.which === 74 && that.control_key_active) {
142 // Move cell down = j
142 // Move cell down = j
143 that.move_cell_down();
143 that.move_cell_down();
144 that.control_key_active = false;
144 that.control_key_active = false;
145 return false;
145 return false;
146 } else if (event.which === 75 && that.control_key_active) {
146 } else if (event.which === 75 && that.control_key_active) {
147 // Move cell up = k
147 // Move cell up = k
148 that.move_cell_up();
148 that.move_cell_up();
149 that.control_key_active = false;
149 that.control_key_active = false;
150 return false;
150 return false;
151 } else if (event.which === 80 && that.control_key_active) {
151 } else if (event.which === 80 && that.control_key_active) {
152 // Select previous = p
152 // Select previous = p
153 that.select_prev();
153 that.select_prev();
154 that.control_key_active = false;
154 that.control_key_active = false;
155 return false;
155 return false;
156 } else if (event.which === 78 && that.control_key_active) {
156 } else if (event.which === 78 && that.control_key_active) {
157 // Select next = n
157 // Select next = n
158 that.select_next();
158 that.select_next();
159 that.control_key_active = false;
159 that.control_key_active = false;
160 return false;
160 return false;
161 } else if (event.which === 76 && that.control_key_active) {
161 } else if (event.which === 76 && that.control_key_active) {
162 // Toggle line numbers = l
162 // Toggle line numbers = l
163 that.cell_toggle_line_numbers();
163 that.cell_toggle_line_numbers();
164 that.control_key_active = false;
164 that.control_key_active = false;
165 return false;
165 return false;
166 } else if (event.which === 73 && that.control_key_active) {
166 } else if (event.which === 73 && that.control_key_active) {
167 // Interrupt kernel = i
167 // Interrupt kernel = i
168 IPython.notebook.kernel.interrupt();
168 IPython.notebook.kernel.interrupt();
169 that.control_key_active = false;
169 that.control_key_active = false;
170 return false;
170 return false;
171 } else if (event.which === 190 && that.control_key_active) {
171 } else if (event.which === 190 && that.control_key_active) {
172 // Restart kernel = . # matches qt console
172 // Restart kernel = . # matches qt console
173 IPython.notebook.restart_kernel();
173 IPython.notebook.restart_kernel();
174 that.control_key_active = false;
174 that.control_key_active = false;
175 return false;
175 return false;
176 } else if (event.which === 72 && that.control_key_active) {
176 } else if (event.which === 72 && that.control_key_active) {
177 // Show keyboard shortcuts = h
177 // Show keyboard shortcuts = h
178 IPython.quick_help.show_keyboard_shortcuts();
178 IPython.quick_help.show_keyboard_shortcuts();
179 that.control_key_active = false;
179 that.control_key_active = false;
180 return false;
180 return false;
181 } else if (that.control_key_active) {
181 } else if (that.control_key_active) {
182 that.control_key_active = false;
182 that.control_key_active = false;
183 return true;
183 return true;
184 };
184 };
185 return true;
185 return true;
186 });
186 });
187
187
188 this.element.bind('collapse_pager', function () {
188 this.element.bind('collapse_pager', function () {
189 var app_height = $('div#main_app').height(); // content height
189 var app_height = $('div#main_app').height(); // content height
190 var splitter_height = $('div#pager_splitter').outerHeight(true);
190 var splitter_height = $('div#pager_splitter').outerHeight(true);
191 var new_height = app_height - splitter_height;
191 var new_height = app_height - splitter_height;
192 that.element.animate({height : new_height + 'px'}, 'fast');
192 that.element.animate({height : new_height + 'px'}, 'fast');
193 });
193 });
194
194
195 this.element.bind('expand_pager', function () {
195 this.element.bind('expand_pager', function () {
196 var app_height = $('div#main_app').height(); // content height
196 var app_height = $('div#main_app').height(); // content height
197 var splitter_height = $('div#pager_splitter').outerHeight(true);
197 var splitter_height = $('div#pager_splitter').outerHeight(true);
198 var pager_height = $('div#pager').outerHeight(true);
198 var pager_height = $('div#pager').outerHeight(true);
199 var new_height = app_height - pager_height - splitter_height;
199 var new_height = app_height - pager_height - splitter_height;
200 that.element.animate({height : new_height + 'px'}, 'fast');
200 that.element.animate({height : new_height + 'px'}, 'fast');
201 });
201 });
202
202
203 $(window).bind('beforeunload', function () {
203 $(window).bind('beforeunload', function () {
204 // TODO: Make killing the kernel configurable.
204 // TODO: Make killing the kernel configurable.
205 var kill_kernel = false;
205 var kill_kernel = false;
206 if (kill_kernel) {
206 if (kill_kernel) {
207 that.kernel.kill();
207 that.kernel.kill();
208 }
208 }
209 if (that.dirty && ! that.read_only) {
209 if (that.dirty && ! that.read_only) {
210 return "You have unsaved changes that will be lost if you leave this page.";
210 return "You have unsaved changes that will be lost if you leave this page.";
211 };
211 };
212 // Null is the *only* return value that will make the browser not
212 // Null is the *only* return value that will make the browser not
213 // pop up the "don't leave" dialog.
213 // pop up the "don't leave" dialog.
214 return null;
214 return null;
215 });
215 });
216 };
216 };
217
217
218
218
219 Notebook.prototype.scroll_to_bottom = function () {
219 Notebook.prototype.scroll_to_bottom = function () {
220 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
220 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 0);
221 };
221 };
222
222
223
223
224 Notebook.prototype.scroll_to_top = function () {
224 Notebook.prototype.scroll_to_top = function () {
225 this.element.animate({scrollTop:0}, 0);
225 this.element.animate({scrollTop:0}, 0);
226 };
226 };
227
227
228
228
229 // Cell indexing, retrieval, etc.
229 // Cell indexing, retrieval, etc.
230
230
231 Notebook.prototype.get_cell_elements = function () {
231 Notebook.prototype.get_cell_elements = function () {
232 return this.element.children("div.cell");
232 return this.element.children("div.cell");
233 };
233 };
234
234
235
235
236 Notebook.prototype.get_cell_element = function (index) {
236 Notebook.prototype.get_cell_element = function (index) {
237 var result = null;
237 var result = null;
238 var e = this.get_cell_elements().eq(index);
238 var e = this.get_cell_elements().eq(index);
239 if (e.length !== 0) {
239 if (e.length !== 0) {
240 result = e;
240 result = e;
241 }
241 }
242 return result;
242 return result;
243 };
243 };
244
244
245
245
246 Notebook.prototype.ncells = function (cell) {
246 Notebook.prototype.ncells = function (cell) {
247 return this.get_cell_elements().length;
247 return this.get_cell_elements().length;
248 };
248 };
249
249
250
250
251 // TODO: we are often calling cells as cells()[i], which we should optimize
251 // TODO: we are often calling cells as cells()[i], which we should optimize
252 // to cells(i) or a new method.
252 // to cells(i) or a new method.
253 Notebook.prototype.get_cells = function () {
253 Notebook.prototype.get_cells = function () {
254 return this.get_cell_elements().toArray().map(function (e) {
254 return this.get_cell_elements().toArray().map(function (e) {
255 return $(e).data("cell");
255 return $(e).data("cell");
256 });
256 });
257 };
257 };
258
258
259
259
260 Notebook.prototype.get_cell = function (index) {
260 Notebook.prototype.get_cell = function (index) {
261 var result = null;
261 var result = null;
262 var ce = this.get_cell_element(index);
262 var ce = this.get_cell_element(index);
263 if (ce !== null) {
263 if (ce !== null) {
264 result = ce.data('cell');
264 result = ce.data('cell');
265 }
265 }
266 return result;
266 return result;
267 }
267 }
268
268
269
269
270 Notebook.prototype.get_next_cell = function (cell) {
270 Notebook.prototype.get_next_cell = function (cell) {
271 var result = null;
271 var result = null;
272 var index = this.find_cell_index(cell);
272 var index = this.find_cell_index(cell);
273 if (index !== null && index < this.ncells()) {
273 if (index !== null && index < this.ncells()) {
274 result = this.get_cell(index+1);
274 result = this.get_cell(index+1);
275 }
275 }
276 return result;
276 return result;
277 }
277 }
278
278
279
279
280 Notebook.prototype.get_prev_cell = function (cell) {
280 Notebook.prototype.get_prev_cell = function (cell) {
281 var result = null;
281 var result = null;
282 var index = this.find_cell_index(cell);
282 var index = this.find_cell_index(cell);
283 if (index !== null && index > 1) {
283 if (index !== null && index > 1) {
284 result = this.get_cell(index-1);
284 result = this.get_cell(index-1);
285 }
285 }
286 return result;
286 return result;
287 }
287 }
288
288
289 Notebook.prototype.find_cell_index = function (cell) {
289 Notebook.prototype.find_cell_index = function (cell) {
290 var result = null;
290 var result = null;
291 this.get_cell_elements().filter(function (index) {
291 this.get_cell_elements().filter(function (index) {
292 if ($(this).data("cell") === cell) {
292 if ($(this).data("cell") === cell) {
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.index_or_selected = function (index) {
300 Notebook.prototype.index_or_selected = function (index) {
301 var i;
301 var i;
302 if (index === undefined || index === null) {
302 if (index === undefined || index === null) {
303 i = this.get_selected_index();
303 i = this.get_selected_index();
304 if (i === null) {
304 if (i === null) {
305 i = 0;
305 i = 0;
306 }
306 }
307 } else {
307 } else {
308 i = index;
308 i = index;
309 }
309 }
310 return i;
310 return i;
311 };
311 };
312
312
313
313
314 Notebook.prototype.get_selected_cell = function () {
314 Notebook.prototype.get_selected_cell = function () {
315 var index = this.get_selected_index();
315 var index = this.get_selected_index();
316 return this.get_cell(index);
316 return this.get_cell(index);
317 };
317 };
318
318
319
319
320 Notebook.prototype.is_valid_cell_index = function (index) {
320 Notebook.prototype.is_valid_cell_index = function (index) {
321 if (index !== null && index >= 0 && index < this.ncells()) {
321 if (index !== null && index >= 0 && index < this.ncells()) {
322 return true;
322 return true;
323 } else {
323 } else {
324 return false;
324 return false;
325 };
325 };
326 }
326 }
327
327
328 Notebook.prototype.get_selected_index = function () {
328 Notebook.prototype.get_selected_index = function () {
329 var result = null;
329 var result = null;
330 this.get_cell_elements().filter(function (index) {
330 this.get_cell_elements().filter(function (index) {
331 if ($(this).data("cell").selected === true) {
331 if ($(this).data("cell").selected === true) {
332 result = index;
332 result = index;
333 };
333 };
334 });
334 });
335 return result;
335 return result;
336 };
336 };
337
337
338
338
339 Notebook.prototype.cell_for_msg = function (msg_id) {
339 Notebook.prototype.cell_for_msg = function (msg_id) {
340 var cell_id = this.msg_cell_map[msg_id];
340 var cell_id = this.msg_cell_map[msg_id];
341 var result = null;
341 var result = null;
342 this.get_cell_elements().filter(function (index) {
342 this.get_cell_elements().filter(function (index) {
343 cell = $(this).data("cell");
343 cell = $(this).data("cell");
344 if (cell.cell_id === cell_id) {
344 if (cell.cell_id === cell_id) {
345 result = cell;
345 result = cell;
346 };
346 };
347 });
347 });
348 return result;
348 return result;
349 };
349 };
350
350
351
351
352 // Cell selection.
352 // Cell selection.
353
353
354 Notebook.prototype.select = function (index) {
354 Notebook.prototype.select = function (index) {
355 if (index !== undefined && index >= 0 && index < this.ncells()) {
355 if (index !== undefined && index >= 0 && index < this.ncells()) {
356 sindex = this.get_selected_index()
356 sindex = this.get_selected_index()
357 if (sindex !== null && index !== sindex) {
357 if (sindex !== null && index !== sindex) {
358 this.get_cell(sindex).unselect();
358 this.get_cell(sindex).unselect();
359 };
359 };
360 this.get_cell(index).select();
360 var cell = this.get_cell(index)
361 cell.select();
362 IPython.toolbar.set_cell_type(cell.cell_type);
361 };
363 };
362 return this;
364 return this;
363 };
365 };
364
366
365
367
366 Notebook.prototype.select_next = function () {
368 Notebook.prototype.select_next = function () {
367 var index = this.get_selected_index();
369 var index = this.get_selected_index();
368 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
370 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
369 this.select(index+1);
371 this.select(index+1);
370 };
372 };
371 return this;
373 return this;
372 };
374 };
373
375
374
376
375 Notebook.prototype.select_prev = function () {
377 Notebook.prototype.select_prev = function () {
376 var index = this.get_selected_index();
378 var index = this.get_selected_index();
377 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
379 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
378 this.select(index-1);
380 this.select(index-1);
379 };
381 };
380 return this;
382 return this;
381 };
383 };
382
384
383
385
384 // Cell movement
386 // Cell movement
385
387
386 Notebook.prototype.move_cell_up = function (index) {
388 Notebook.prototype.move_cell_up = function (index) {
387 var i = this.index_or_selected();
389 var i = this.index_or_selected();
388 if (i !== null && i < this.ncells() && i > 0) {
390 if (i !== null && i < this.ncells() && i > 0) {
389 var pivot = this.get_cell_element(i-1);
391 var pivot = this.get_cell_element(i-1);
390 var tomove = this.get_cell_element(i);
392 var tomove = this.get_cell_element(i);
391 if (pivot !== null && tomove !== null) {
393 if (pivot !== null && tomove !== null) {
392 tomove.detach();
394 tomove.detach();
393 pivot.before(tomove);
395 pivot.before(tomove);
394 this.select(i-1);
396 this.select(i-1);
395 };
397 };
396 };
398 };
397 this.dirty = true;
399 this.dirty = true;
398 return this;
400 return this;
399 };
401 };
400
402
401
403
402 Notebook.prototype.move_cell_down = function (index) {
404 Notebook.prototype.move_cell_down = function (index) {
403 var i = this.index_or_selected();
405 var i = this.index_or_selected();
404 if (i !== null && i < (this.ncells()-1) && i >= 0) {
406 if (i !== null && i < (this.ncells()-1) && i >= 0) {
405 var pivot = this.get_cell_element(i+1);
407 var pivot = this.get_cell_element(i+1);
406 var tomove = this.get_cell_element(i);
408 var tomove = this.get_cell_element(i);
407 if (pivot !== null && tomove !== null) {
409 if (pivot !== null && tomove !== null) {
408 tomove.detach();
410 tomove.detach();
409 pivot.after(tomove);
411 pivot.after(tomove);
410 this.select(i+1);
412 this.select(i+1);
411 };
413 };
412 };
414 };
413 this.dirty = true;
415 this.dirty = true;
414 return this;
416 return this;
415 };
417 };
416
418
417
419
418 Notebook.prototype.sort_cells = function () {
420 Notebook.prototype.sort_cells = function () {
419 // This is not working right now. Calling this will actually crash
421 // This is not working right now. Calling this will actually crash
420 // the browser. I think there is an infinite loop in here...
422 // the browser. I think there is an infinite loop in here...
421 var ncells = this.ncells();
423 var ncells = this.ncells();
422 var sindex = this.get_selected_index();
424 var sindex = this.get_selected_index();
423 var swapped;
425 var swapped;
424 do {
426 do {
425 swapped = false;
427 swapped = false;
426 for (var i=1; i<ncells; i++) {
428 for (var i=1; i<ncells; i++) {
427 current = this.get_cell(i);
429 current = this.get_cell(i);
428 previous = this.get_cell(i-1);
430 previous = this.get_cell(i-1);
429 if (previous.input_prompt_number > current.input_prompt_number) {
431 if (previous.input_prompt_number > current.input_prompt_number) {
430 this.move_cell_up(i);
432 this.move_cell_up(i);
431 swapped = true;
433 swapped = true;
432 };
434 };
433 };
435 };
434 } while (swapped);
436 } while (swapped);
435 this.select(sindex);
437 this.select(sindex);
436 return this;
438 return this;
437 };
439 };
438
440
439 // Insertion, deletion.
441 // Insertion, deletion.
440
442
441 Notebook.prototype.delete_cell = function (index) {
443 Notebook.prototype.delete_cell = function (index) {
442 var i = this.index_or_selected(index);
444 var i = this.index_or_selected(index);
443 if (this.is_valid_cell_index(i)) {
445 if (this.is_valid_cell_index(i)) {
444 var ce = this.get_cell_element(i);
446 var ce = this.get_cell_element(i);
445 ce.remove();
447 ce.remove();
446 if (i === (this.ncells())) {
448 if (i === (this.ncells())) {
447 this.select(i-1);
449 this.select(i-1);
448 } else {
450 } else {
449 this.select(i);
451 this.select(i);
450 };
452 };
451 this.dirty = true;
453 this.dirty = true;
452 };
454 };
453 return this;
455 return this;
454 };
456 };
455
457
456
458
457 Notebook.prototype.insert_cell_below = function (type, index) {
459 Notebook.prototype.insert_cell_below = function (type, index) {
458 // type = ('code','html','markdown')
460 // type = ('code','html','markdown')
459 // index = cell index or undefined to insert below selected
461 // index = cell index or undefined to insert below selected
460 index = this.index_or_selected(index);
462 index = this.index_or_selected(index);
461 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
463 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
462 var cell = null;
464 var cell = null;
463 if (type === 'code') {
465 if (type === 'code') {
464 var cell = new IPython.CodeCell(this);
466 var cell = new IPython.CodeCell(this);
465 cell.set_input_prompt();
467 cell.set_input_prompt();
466 } else if (type === 'markdown') {
468 } else if (type === 'markdown') {
467 var cell = new IPython.MarkdownCell(this);
469 var cell = new IPython.MarkdownCell(this);
468 } else if (type === 'html') {
470 } else if (type === 'html') {
469 var cell = new IPython.HTMLCell(this);
471 var cell = new IPython.HTMLCell(this);
470 };
472 };
471 if (cell !== null) {
473 if (cell !== null) {
472 if (this.ncells() === 0) {
474 if (this.ncells() === 0) {
473 this.element.find('div.end_space').before(cell.element);
475 this.element.find('div.end_space').before(cell.element);
474 } else if (this.is_valid_cell_index(index)) {
476 } else if (this.is_valid_cell_index(index)) {
475 this.get_cell_element(index).after(cell.element);
477 this.get_cell_element(index).after(cell.element);
476 };
478 };
477 cell.render();
479 cell.render();
478 this.select(this.find_cell_index(cell));
480 this.select(this.find_cell_index(cell));
479 this.dirty = true;
481 this.dirty = true;
480 return cell;
482 return cell;
481 };
483 };
482 };
484 };
483 };
485 };
484
486
485
487
486 Notebook.prototype.insert_cell_above = function (type, index) {
488 Notebook.prototype.insert_cell_above = function (type, index) {
487 // type = ('code','html','markdown')
489 // type = ('code','html','markdown')
488 // index = cell index or undefined to insert above selected
490 // index = cell index or undefined to insert above selected
489 index = this.index_or_selected(index);
491 index = this.index_or_selected(index);
490 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
492 if (this.ncells() === 0 || this.is_valid_cell_index(index)) {
491 var cell = null;
493 var cell = null;
492 if (type === 'code') {
494 if (type === 'code') {
493 var cell = new IPython.CodeCell(this);
495 var cell = new IPython.CodeCell(this);
494 cell.set_input_prompt();
496 cell.set_input_prompt();
495 } else if (type === 'markdown') {
497 } else if (type === 'markdown') {
496 var cell = new IPython.MarkdownCell(this);
498 var cell = new IPython.MarkdownCell(this);
497 } else if (type === 'html') {
499 } else if (type === 'html') {
498 var cell = new IPython.HTMLCell(this);
500 var cell = new IPython.HTMLCell(this);
499 };
501 };
500 if (cell !== null) {
502 if (cell !== null) {
501 if (this.ncells() === 0) {
503 if (this.ncells() === 0) {
502 this.element.find('div.end_space').before(cell.element);
504 this.element.find('div.end_space').before(cell.element);
503 } else if (this.is_valid_cell_index(index)) {
505 } else if (this.is_valid_cell_index(index)) {
504 this.get_cell_element(index).before(cell.element);
506 this.get_cell_element(index).before(cell.element);
505 };
507 };
506 cell.render();
508 cell.render();
507 this.select(this.find_cell_index(cell));
509 this.select(this.find_cell_index(cell));
508 this.dirty = true;
510 this.dirty = true;
509 return cell;
511 return cell;
510 };
512 };
511 };
513 };
512 };
514 };
513
515
514
516
515 Notebook.prototype.to_code = function (index) {
517 Notebook.prototype.to_code = function (index) {
516 var i = this.index_or_selected(index);
518 var i = this.index_or_selected(index);
517 if (this.is_valid_cell_index(i)) {
519 if (this.is_valid_cell_index(i)) {
518 var source_element = this.get_cell_element(i);
520 var source_element = this.get_cell_element(i);
519 var source_cell = source_element.data("cell");
521 var source_cell = source_element.data("cell");
520 if (!(source_cell instanceof IPython.CodeCell)) {
522 if (!(source_cell instanceof IPython.CodeCell)) {
521 target_cell = this.insert_cell_below('code',i);
523 target_cell = this.insert_cell_below('code',i);
522 var text = source_cell.get_text();
524 var text = source_cell.get_text();
523 if (text === source_cell.placeholder) {
525 if (text === source_cell.placeholder) {
524 text = '';
526 text = '';
525 }
527 }
526 target_cell.set_text(text);
528 target_cell.set_text(text);
527 source_element.remove();
529 source_element.remove();
528 };
530 };
529 this.dirty = true;
531 this.dirty = true;
530 };
532 };
531 };
533 };
532
534
533
535
534 Notebook.prototype.to_markdown = function (index) {
536 Notebook.prototype.to_markdown = function (index) {
535 var i = this.index_or_selected(index);
537 var i = this.index_or_selected(index);
536 if (this.is_valid_cell_index(i)) {
538 if (this.is_valid_cell_index(i)) {
537 var source_element = this.get_cell_element(i);
539 var source_element = this.get_cell_element(i);
538 var source_cell = source_element.data("cell");
540 var source_cell = source_element.data("cell");
539 var target_cell = null;
541 var target_cell = null;
540 if (!(source_cell instanceof IPython.MarkdownCell)) {
542 if (!(source_cell instanceof IPython.MarkdownCell)) {
541 target_cell = this.insert_cell_below('markdown',i);
543 target_cell = this.insert_cell_below('markdown',i);
542 var text = source_cell.get_text();
544 var text = source_cell.get_text();
543 if (text === source_cell.placeholder) {
545 if (text === source_cell.placeholder) {
544 text = '';
546 text = '';
545 };
547 };
546 if (target_cell !== null) {
548 if (target_cell !== null) {
547 // The edit must come before the set_text.
549 // The edit must come before the set_text.
548 target_cell.edit();
550 target_cell.edit();
549 target_cell.set_text(text);
551 target_cell.set_text(text);
550 source_element.remove();
552 source_element.remove();
551 }
553 }
552 this.dirty = true;
554 this.dirty = true;
553 };
555 };
554 };
556 };
555 };
557 };
556
558
557
559
558 Notebook.prototype.to_html = function (index) {
560 Notebook.prototype.to_html = function (index) {
559 var i = this.index_or_selected(index);
561 var i = this.index_or_selected(index);
560 if (this.is_valid_cell_index(i)) {
562 if (this.is_valid_cell_index(i)) {
561 var source_element = this.get_cell_element(i);
563 var source_element = this.get_cell_element(i);
562 var source_cell = source_element.data("cell");
564 var source_cell = source_element.data("cell");
563 var target_cell = null;
565 var target_cell = null;
564 if (!(source_cell instanceof IPython.HTMLCell)) {
566 if (!(source_cell instanceof IPython.HTMLCell)) {
565 target_cell = this.insert_cell_below('html',i);
567 target_cell = this.insert_cell_below('html',i);
566 var text = source_cell.get_text();
568 var text = source_cell.get_text();
567 if (text === source_cell.placeholder) {
569 if (text === source_cell.placeholder) {
568 text = '';
570 text = '';
569 };
571 };
570 if (target_cell !== null) {
572 if (target_cell !== null) {
571 // The edit must come before the set_text.
573 // The edit must come before the set_text.
572 target_cell.edit();
574 target_cell.edit();
573 target_cell.set_text(text);
575 target_cell.set_text(text);
574 source_element.remove();
576 source_element.remove();
575 }
577 }
576 this.dirty = true;
578 this.dirty = true;
577 };
579 };
578 };
580 };
579 };
581 };
580
582
581
583
582 // Cut/Copy/Paste
584 // Cut/Copy/Paste
583
585
584 Notebook.prototype.enable_paste = function () {
586 Notebook.prototype.enable_paste = function () {
585 var that = this;
587 var that = this;
586 if (!this.paste_enabled) {
588 if (!this.paste_enabled) {
587 $('#paste_cell').removeClass('ui-state-disabled')
589 $('#paste_cell').removeClass('ui-state-disabled')
588 .on('click', function () {that.paste_cell();});
590 .on('click', function () {that.paste_cell();});
589 $('#paste_cell_above').removeClass('ui-state-disabled')
591 $('#paste_cell_above').removeClass('ui-state-disabled')
590 .on('click', function () {that.paste_cell_above();});
592 .on('click', function () {that.paste_cell_above();});
591 $('#paste_cell_below').removeClass('ui-state-disabled')
593 $('#paste_cell_below').removeClass('ui-state-disabled')
592 .on('click', function () {that.paste_cell_below();});
594 .on('click', function () {that.paste_cell_below();});
593 this.paste_enabled = true;
595 this.paste_enabled = true;
594 };
596 };
595 };
597 };
596
598
597
599
598 Notebook.prototype.disable_paste = function () {
600 Notebook.prototype.disable_paste = function () {
599 if (this.paste_enabled) {
601 if (this.paste_enabled) {
600 $('#paste_cell').addClass('ui-state-disabled').off('click');
602 $('#paste_cell').addClass('ui-state-disabled').off('click');
601 $('#paste_cell_above').addClass('ui-state-disabled').off('click');
603 $('#paste_cell_above').addClass('ui-state-disabled').off('click');
602 $('#paste_cell_below').addClass('ui-state-disabled').off('click');
604 $('#paste_cell_below').addClass('ui-state-disabled').off('click');
603 this.paste_enabled = false;
605 this.paste_enabled = false;
604 };
606 };
605 };
607 };
606
608
607
609
608 Notebook.prototype.cut_cell = function () {
610 Notebook.prototype.cut_cell = function () {
609 this.copy_cell();
611 this.copy_cell();
610 this.delete_cell();
612 this.delete_cell();
611 }
613 }
612
614
613 Notebook.prototype.copy_cell = function () {
615 Notebook.prototype.copy_cell = function () {
614 var cell = this.get_selected_cell();
616 var cell = this.get_selected_cell();
615 this.clipboard = cell.toJSON();
617 this.clipboard = cell.toJSON();
616 this.enable_paste();
618 this.enable_paste();
617 };
619 };
618
620
619
621
620 Notebook.prototype.paste_cell = function () {
622 Notebook.prototype.paste_cell = function () {
621 if (this.clipboard !== null && this.paste_enabled) {
623 if (this.clipboard !== null && this.paste_enabled) {
622 var cell_data = this.clipboard;
624 var cell_data = this.clipboard;
623 var new_cell = this.insert_cell_above(cell_data.cell_type);
625 var new_cell = this.insert_cell_above(cell_data.cell_type);
624 new_cell.fromJSON(cell_data);
626 new_cell.fromJSON(cell_data);
625 old_cell = this.get_next_cell(new_cell);
627 old_cell = this.get_next_cell(new_cell);
626 this.delete_cell(this.find_cell_index(old_cell));
628 this.delete_cell(this.find_cell_index(old_cell));
627 this.select(this.find_cell_index(new_cell));
629 this.select(this.find_cell_index(new_cell));
628 };
630 };
629 };
631 };
630
632
631
633
632 Notebook.prototype.paste_cell_above = function () {
634 Notebook.prototype.paste_cell_above = function () {
633 if (this.clipboard !== null && this.paste_enabled) {
635 if (this.clipboard !== null && this.paste_enabled) {
634 var cell_data = this.clipboard;
636 var cell_data = this.clipboard;
635 var new_cell = this.insert_cell_above(cell_data.cell_type);
637 var new_cell = this.insert_cell_above(cell_data.cell_type);
636 new_cell.fromJSON(cell_data);
638 new_cell.fromJSON(cell_data);
637 };
639 };
638 };
640 };
639
641
640
642
641 Notebook.prototype.paste_cell_below = function () {
643 Notebook.prototype.paste_cell_below = function () {
642 if (this.clipboard !== null && this.paste_enabled) {
644 if (this.clipboard !== null && this.paste_enabled) {
643 var cell_data = this.clipboard;
645 var cell_data = this.clipboard;
644 var new_cell = this.insert_cell_below(cell_data.cell_type);
646 var new_cell = this.insert_cell_below(cell_data.cell_type);
645 new_cell.fromJSON(cell_data);
647 new_cell.fromJSON(cell_data);
646 };
648 };
647 };
649 };
648
650
649
651
650 // Split/merge
652 // Split/merge
651
653
652 Notebook.prototype.split_cell = function () {
654 Notebook.prototype.split_cell = function () {
653 // Todo: implement spliting for other cell types.
655 // Todo: implement spliting for other cell types.
654 var cell = this.get_selected_cell();
656 var cell = this.get_selected_cell();
655 if (cell.is_splittable()) {
657 if (cell.is_splittable()) {
656 texta = cell.get_pre_cursor();
658 texta = cell.get_pre_cursor();
657 textb = cell.get_post_cursor();
659 textb = cell.get_post_cursor();
658 if (cell instanceof IPython.CodeCell) {
660 if (cell instanceof IPython.CodeCell) {
659 cell.set_text(texta);
661 cell.set_text(texta);
660 var new_cell = this.insert_cell_below('code');
662 var new_cell = this.insert_cell_below('code');
661 new_cell.set_text(textb);
663 new_cell.set_text(textb);
662 } else if (cell instanceof IPython.MarkdownCell) {
664 } else if (cell instanceof IPython.MarkdownCell) {
663 cell.set_text(texta);
665 cell.set_text(texta);
664 cell.render();
666 cell.render();
665 var new_cell = this.insert_cell_below('markdown');
667 var new_cell = this.insert_cell_below('markdown');
666 new_cell.edit(); // editor must be visible to call set_text
668 new_cell.edit(); // editor must be visible to call set_text
667 new_cell.set_text(textb);
669 new_cell.set_text(textb);
668 new_cell.render();
670 new_cell.render();
669 } else if (cell instanceof IPython.HTMLCell) {
671 } else if (cell instanceof IPython.HTMLCell) {
670 cell.set_text(texta);
672 cell.set_text(texta);
671 cell.render();
673 cell.render();
672 var new_cell = this.insert_cell_below('html');
674 var new_cell = this.insert_cell_below('html');
673 new_cell.edit(); // editor must be visible to call set_text
675 new_cell.edit(); // editor must be visible to call set_text
674 new_cell.set_text(textb);
676 new_cell.set_text(textb);
675 new_cell.render();
677 new_cell.render();
676 };
678 };
677 };
679 };
678 };
680 };
679
681
680
682
681 Notebook.prototype.merge_cell_above = function () {
683 Notebook.prototype.merge_cell_above = function () {
682 var index = this.get_selected_index();
684 var index = this.get_selected_index();
683 var cell = this.get_cell(index);
685 var cell = this.get_cell(index);
684 if (index > 0) {
686 if (index > 0) {
685 upper_cell = this.get_cell(index-1);
687 upper_cell = this.get_cell(index-1);
686 upper_text = upper_cell.get_text();
688 upper_text = upper_cell.get_text();
687 text = cell.get_text();
689 text = cell.get_text();
688 if (cell instanceof IPython.CodeCell) {
690 if (cell instanceof IPython.CodeCell) {
689 cell.set_text(upper_text+'\n'+text);
691 cell.set_text(upper_text+'\n'+text);
690 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
692 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
691 cell.edit();
693 cell.edit();
692 cell.set_text(upper_text+'\n'+text);
694 cell.set_text(upper_text+'\n'+text);
693 cell.render();
695 cell.render();
694 };
696 };
695 this.delete_cell(index-1);
697 this.delete_cell(index-1);
696 this.select(this.find_cell_index(cell));
698 this.select(this.find_cell_index(cell));
697 };
699 };
698 };
700 };
699
701
700
702
701 Notebook.prototype.merge_cell_below = function () {
703 Notebook.prototype.merge_cell_below = function () {
702 var index = this.get_selected_index();
704 var index = this.get_selected_index();
703 var cell = this.get_cell(index);
705 var cell = this.get_cell(index);
704 if (index < this.ncells()-1) {
706 if (index < this.ncells()-1) {
705 lower_cell = this.get_cell(index+1);
707 lower_cell = this.get_cell(index+1);
706 lower_text = lower_cell.get_text();
708 lower_text = lower_cell.get_text();
707 text = cell.get_text();
709 text = cell.get_text();
708 if (cell instanceof IPython.CodeCell) {
710 if (cell instanceof IPython.CodeCell) {
709 cell.set_text(text+'\n'+lower_text);
711 cell.set_text(text+'\n'+lower_text);
710 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
712 } else if (cell instanceof IPython.MarkdownCell || cell instanceof IPython.HTMLCell) {
711 cell.edit();
713 cell.edit();
712 cell.set_text(text+'\n'+lower_text);
714 cell.set_text(text+'\n'+lower_text);
713 cell.render();
715 cell.render();
714 };
716 };
715 this.delete_cell(index+1);
717 this.delete_cell(index+1);
716 this.select(this.find_cell_index(cell));
718 this.select(this.find_cell_index(cell));
717 };
719 };
718 };
720 };
719
721
720
722
721 // Cell collapsing and output clearing
723 // Cell collapsing and output clearing
722
724
723 Notebook.prototype.collapse = function (index) {
725 Notebook.prototype.collapse = function (index) {
724 var i = this.index_or_selected(index);
726 var i = this.index_or_selected(index);
725 this.get_cell(i).collapse();
727 this.get_cell(i).collapse();
726 this.dirty = true;
728 this.dirty = true;
727 };
729 };
728
730
729
731
730 Notebook.prototype.expand = function (index) {
732 Notebook.prototype.expand = function (index) {
731 var i = this.index_or_selected(index);
733 var i = this.index_or_selected(index);
732 this.get_cell(i).expand();
734 this.get_cell(i).expand();
733 this.dirty = true;
735 this.dirty = true;
734 };
736 };
735
737
736
738
737 Notebook.prototype.toggle_output = function (index) {
739 Notebook.prototype.toggle_output = function (index) {
738 var i = this.index_or_selected(index);
740 var i = this.index_or_selected(index);
739 this.get_cell(i).toggle_output();
741 this.get_cell(i).toggle_output();
740 this.dirty = true;
742 this.dirty = true;
741 };
743 };
742
744
743
745
744 Notebook.prototype.set_timebeforetooltip = function (time) {
746 Notebook.prototype.set_timebeforetooltip = function (time) {
745 this.time_before_tooltip = time;
747 this.time_before_tooltip = time;
746 };
748 };
747
749
748
750
749 Notebook.prototype.set_tooltipontab = function (state) {
751 Notebook.prototype.set_tooltipontab = function (state) {
750 this.tooltip_on_tab = state;
752 this.tooltip_on_tab = state;
751 };
753 };
752
754
753
755
754 Notebook.prototype.set_smartcompleter = function (state) {
756 Notebook.prototype.set_smartcompleter = function (state) {
755 this.smart_completer = state;
757 this.smart_completer = state;
756 };
758 };
757
759
758
760
759 Notebook.prototype.clear_all_output = function () {
761 Notebook.prototype.clear_all_output = function () {
760 var ncells = this.ncells();
762 var ncells = this.ncells();
761 var cells = this.get_cells();
763 var cells = this.get_cells();
762 for (var i=0; i<ncells; i++) {
764 for (var i=0; i<ncells; i++) {
763 if (cells[i] instanceof IPython.CodeCell) {
765 if (cells[i] instanceof IPython.CodeCell) {
764 cells[i].clear_output(true,true,true);
766 cells[i].clear_output(true,true,true);
765 }
767 }
766 };
768 };
767 this.dirty = true;
769 this.dirty = true;
768 };
770 };
769
771
770
772
771 // Other cell functions: line numbers, ...
773 // Other cell functions: line numbers, ...
772
774
773 Notebook.prototype.cell_toggle_line_numbers = function() {
775 Notebook.prototype.cell_toggle_line_numbers = function() {
774 this.get_selected_cell().toggle_line_numbers();
776 this.get_selected_cell().toggle_line_numbers();
775 };
777 };
776
778
777 // Kernel related things
779 // Kernel related things
778
780
779 Notebook.prototype.start_kernel = function () {
781 Notebook.prototype.start_kernel = function () {
780 this.kernel = new IPython.Kernel();
782 this.kernel = new IPython.Kernel();
781 var notebook_id = IPython.save_widget.get_notebook_id();
783 var notebook_id = IPython.save_widget.get_notebook_id();
782 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
784 this.kernel.start(notebook_id, $.proxy(this.kernel_started, this));
783 };
785 };
784
786
785
787
786 Notebook.prototype.restart_kernel = function () {
788 Notebook.prototype.restart_kernel = function () {
787 var that = this;
789 var that = this;
788 var notebook_id = IPython.save_widget.get_notebook_id();
790 var notebook_id = IPython.save_widget.get_notebook_id();
789
791
790 var dialog = $('<div/>');
792 var dialog = $('<div/>');
791 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
793 dialog.html('Do you want to restart the current kernel? You will lose all variables defined in it.');
792 $(document).append(dialog);
794 $(document).append(dialog);
793 dialog.dialog({
795 dialog.dialog({
794 resizable: false,
796 resizable: false,
795 modal: true,
797 modal: true,
796 title: "Restart kernel or continue running?",
798 title: "Restart kernel or continue running?",
797 closeText: '',
799 closeText: '',
798 buttons : {
800 buttons : {
799 "Restart": function () {
801 "Restart": function () {
800 that.kernel.restart($.proxy(that.kernel_started, that));
802 that.kernel.restart($.proxy(that.kernel_started, that));
801 $(this).dialog('close');
803 $(this).dialog('close');
802 },
804 },
803 "Continue running": function () {
805 "Continue running": function () {
804 $(this).dialog('close');
806 $(this).dialog('close');
805 }
807 }
806 }
808 }
807 });
809 });
808 };
810 };
809
811
810
812
811 Notebook.prototype.kernel_started = function () {
813 Notebook.prototype.kernel_started = function () {
812 console.log("Kernel started: ", this.kernel.kernel_id);
814 console.log("Kernel started: ", this.kernel.kernel_id);
813 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
815 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
814 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
816 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
815 };
817 };
816
818
817
819
818 Notebook.prototype.handle_shell_reply = function (e) {
820 Notebook.prototype.handle_shell_reply = function (e) {
819 reply = $.parseJSON(e.data);
821 reply = $.parseJSON(e.data);
820 var header = reply.header;
822 var header = reply.header;
821 var content = reply.content;
823 var content = reply.content;
822 var msg_type = header.msg_type;
824 var msg_type = header.msg_type;
823 // console.log(reply);
825 // console.log(reply);
824 var cell = this.cell_for_msg(reply.parent_header.msg_id);
826 var cell = this.cell_for_msg(reply.parent_header.msg_id);
825 if (msg_type === "execute_reply") {
827 if (msg_type === "execute_reply") {
826 cell.set_input_prompt(content.execution_count);
828 cell.set_input_prompt(content.execution_count);
827 cell.element.removeClass("running");
829 cell.element.removeClass("running");
828 this.dirty = true;
830 this.dirty = true;
829 } else if (msg_type === "complete_reply") {
831 } else if (msg_type === "complete_reply") {
830 cell.finish_completing(content.matched_text, content.matches);
832 cell.finish_completing(content.matched_text, content.matches);
831 } else if (msg_type === "object_info_reply"){
833 } else if (msg_type === "object_info_reply"){
832 //console.log('back from object_info_request : ')
834 //console.log('back from object_info_request : ')
833 rep = reply.content;
835 rep = reply.content;
834 if(rep.found)
836 if(rep.found)
835 {
837 {
836 cell.finish_tooltip(rep);
838 cell.finish_tooltip(rep);
837 }
839 }
838 } else {
840 } else {
839 //console.log("unknown reply:"+msg_type);
841 //console.log("unknown reply:"+msg_type);
840 }
842 }
841 // when having a rely from object_info_reply,
843 // when having a rely from object_info_reply,
842 // no payload so no nned to handle it
844 // no payload so no nned to handle it
843 if(typeof(content.payload)!='undefined') {
845 if(typeof(content.payload)!='undefined') {
844 var payload = content.payload || [];
846 var payload = content.payload || [];
845 this.handle_payload(cell, payload);
847 this.handle_payload(cell, payload);
846 }
848 }
847 };
849 };
848
850
849
851
850 Notebook.prototype.handle_payload = function (cell, payload) {
852 Notebook.prototype.handle_payload = function (cell, payload) {
851 var l = payload.length;
853 var l = payload.length;
852 for (var i=0; i<l; i++) {
854 for (var i=0; i<l; i++) {
853 if (payload[i].source === 'IPython.zmq.page.page') {
855 if (payload[i].source === 'IPython.zmq.page.page') {
854 if (payload[i].text.trim() !== '') {
856 if (payload[i].text.trim() !== '') {
855 IPython.pager.clear();
857 IPython.pager.clear();
856 IPython.pager.expand();
858 IPython.pager.expand();
857 IPython.pager.append_text(payload[i].text);
859 IPython.pager.append_text(payload[i].text);
858 }
860 }
859 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
861 } else if (payload[i].source === 'IPython.zmq.zmqshell.ZMQInteractiveShell.set_next_input') {
860 var index = this.find_cell_index(cell);
862 var index = this.find_cell_index(cell);
861 var new_cell = this.insert_cell_below('code',index);
863 var new_cell = this.insert_cell_below('code',index);
862 new_cell.set_text(payload[i].text);
864 new_cell.set_text(payload[i].text);
863 this.dirty = true;
865 this.dirty = true;
864 }
866 }
865 };
867 };
866 };
868 };
867
869
868
870
869 Notebook.prototype.handle_iopub_reply = function (e) {
871 Notebook.prototype.handle_iopub_reply = function (e) {
870 reply = $.parseJSON(e.data);
872 reply = $.parseJSON(e.data);
871 var content = reply.content;
873 var content = reply.content;
872 // console.log(reply);
874 // console.log(reply);
873 var msg_type = reply.header.msg_type;
875 var msg_type = reply.header.msg_type;
874 var cell = this.cell_for_msg(reply.parent_header.msg_id);
876 var cell = this.cell_for_msg(reply.parent_header.msg_id);
875 if (msg_type !== 'status' && !cell){
877 if (msg_type !== 'status' && !cell){
876 // message not from this notebook, but should be attached to a cell
878 // message not from this notebook, but should be attached to a cell
877 console.log("Received IOPub message not caused by one of my cells");
879 console.log("Received IOPub message not caused by one of my cells");
878 console.log(reply);
880 console.log(reply);
879 return;
881 return;
880 }
882 }
881 var output_types = ['stream','display_data','pyout','pyerr'];
883 var output_types = ['stream','display_data','pyout','pyerr'];
882 if (output_types.indexOf(msg_type) >= 0) {
884 if (output_types.indexOf(msg_type) >= 0) {
883 this.handle_output(cell, msg_type, content);
885 this.handle_output(cell, msg_type, content);
884 } else if (msg_type === 'status') {
886 } else if (msg_type === 'status') {
885 if (content.execution_state === 'busy') {
887 if (content.execution_state === 'busy') {
886 IPython.kernel_status_widget.status_busy();
888 IPython.kernel_status_widget.status_busy();
887 } else if (content.execution_state === 'idle') {
889 } else if (content.execution_state === 'idle') {
888 IPython.kernel_status_widget.status_idle();
890 IPython.kernel_status_widget.status_idle();
889 } else if (content.execution_state === 'dead') {
891 } else if (content.execution_state === 'dead') {
890 this.handle_status_dead();
892 this.handle_status_dead();
891 };
893 };
892 } else if (msg_type === 'clear_output') {
894 } else if (msg_type === 'clear_output') {
893 cell.clear_output(content.stdout, content.stderr, content.other);
895 cell.clear_output(content.stdout, content.stderr, content.other);
894 };
896 };
895 };
897 };
896
898
897
899
898 Notebook.prototype.handle_status_dead = function () {
900 Notebook.prototype.handle_status_dead = function () {
899 var that = this;
901 var that = this;
900 this.kernel.stop_channels();
902 this.kernel.stop_channels();
901 var dialog = $('<div/>');
903 var dialog = $('<div/>');
902 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.');
904 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.');
903 $(document).append(dialog);
905 $(document).append(dialog);
904 dialog.dialog({
906 dialog.dialog({
905 resizable: false,
907 resizable: false,
906 modal: true,
908 modal: true,
907 title: "Dead kernel",
909 title: "Dead kernel",
908 buttons : {
910 buttons : {
909 "Restart": function () {
911 "Restart": function () {
910 that.start_kernel();
912 that.start_kernel();
911 $(this).dialog('close');
913 $(this).dialog('close');
912 },
914 },
913 "Continue running": function () {
915 "Continue running": function () {
914 $(this).dialog('close');
916 $(this).dialog('close');
915 }
917 }
916 }
918 }
917 });
919 });
918 };
920 };
919
921
920
922
921 Notebook.prototype.handle_output = function (cell, msg_type, content) {
923 Notebook.prototype.handle_output = function (cell, msg_type, content) {
922 var json = {};
924 var json = {};
923 json.output_type = msg_type;
925 json.output_type = msg_type;
924 if (msg_type === "stream") {
926 if (msg_type === "stream") {
925 json.text = content.data;
927 json.text = content.data;
926 json.stream = content.name;
928 json.stream = content.name;
927 } else if (msg_type === "display_data") {
929 } else if (msg_type === "display_data") {
928 json = this.convert_mime_types(json, content.data);
930 json = this.convert_mime_types(json, content.data);
929 } else if (msg_type === "pyout") {
931 } else if (msg_type === "pyout") {
930 json.prompt_number = content.execution_count;
932 json.prompt_number = content.execution_count;
931 json = this.convert_mime_types(json, content.data);
933 json = this.convert_mime_types(json, content.data);
932 } else if (msg_type === "pyerr") {
934 } else if (msg_type === "pyerr") {
933 json.ename = content.ename;
935 json.ename = content.ename;
934 json.evalue = content.evalue;
936 json.evalue = content.evalue;
935 json.traceback = content.traceback;
937 json.traceback = content.traceback;
936 };
938 };
937 cell.append_output(json);
939 cell.append_output(json);
938 this.dirty = true;
940 this.dirty = true;
939 };
941 };
940
942
941
943
942 Notebook.prototype.convert_mime_types = function (json, data) {
944 Notebook.prototype.convert_mime_types = function (json, data) {
943 if (data['text/plain'] !== undefined) {
945 if (data['text/plain'] !== undefined) {
944 json.text = data['text/plain'];
946 json.text = data['text/plain'];
945 };
947 };
946 if (data['text/html'] !== undefined) {
948 if (data['text/html'] !== undefined) {
947 json.html = data['text/html'];
949 json.html = data['text/html'];
948 };
950 };
949 if (data['image/svg+xml'] !== undefined) {
951 if (data['image/svg+xml'] !== undefined) {
950 json.svg = data['image/svg+xml'];
952 json.svg = data['image/svg+xml'];
951 };
953 };
952 if (data['image/png'] !== undefined) {
954 if (data['image/png'] !== undefined) {
953 json.png = data['image/png'];
955 json.png = data['image/png'];
954 };
956 };
955 if (data['image/jpeg'] !== undefined) {
957 if (data['image/jpeg'] !== undefined) {
956 json.jpeg = data['image/jpeg'];
958 json.jpeg = data['image/jpeg'];
957 };
959 };
958 if (data['text/latex'] !== undefined) {
960 if (data['text/latex'] !== undefined) {
959 json.latex = data['text/latex'];
961 json.latex = data['text/latex'];
960 };
962 };
961 if (data['application/json'] !== undefined) {
963 if (data['application/json'] !== undefined) {
962 json.json = data['application/json'];
964 json.json = data['application/json'];
963 };
965 };
964 if (data['application/javascript'] !== undefined) {
966 if (data['application/javascript'] !== undefined) {
965 json.javascript = data['application/javascript'];
967 json.javascript = data['application/javascript'];
966 }
968 }
967 return json;
969 return json;
968 };
970 };
969
971
970
972
971 Notebook.prototype.execute_selected_cell = function (options) {
973 Notebook.prototype.execute_selected_cell = function (options) {
972 // add_new: should a new cell be added if we are at the end of the nb
974 // add_new: should a new cell be added if we are at the end of the nb
973 // terminal: execute in terminal mode, which stays in the current cell
975 // terminal: execute in terminal mode, which stays in the current cell
974 default_options = {terminal: false, add_new: true};
976 default_options = {terminal: false, add_new: true};
975 $.extend(default_options, options);
977 $.extend(default_options, options);
976 var that = this;
978 var that = this;
977 var cell = that.get_selected_cell();
979 var cell = that.get_selected_cell();
978 var cell_index = that.find_cell_index(cell);
980 var cell_index = that.find_cell_index(cell);
979 if (cell instanceof IPython.CodeCell) {
981 if (cell instanceof IPython.CodeCell) {
980 cell.clear_output(true, true, true);
982 cell.clear_output(true, true, true);
981 cell.set_input_prompt('*');
983 cell.set_input_prompt('*');
982 cell.element.addClass("running");
984 cell.element.addClass("running");
983 var code = cell.get_text();
985 var code = cell.get_text();
984 var msg_id = that.kernel.execute(cell.get_text());
986 var msg_id = that.kernel.execute(cell.get_text());
985 that.msg_cell_map[msg_id] = cell.cell_id;
987 that.msg_cell_map[msg_id] = cell.cell_id;
986 } else if (cell instanceof IPython.HTMLCell) {
988 } else if (cell instanceof IPython.HTMLCell) {
987 cell.render();
989 cell.render();
988 }
990 }
989 if (default_options.terminal) {
991 if (default_options.terminal) {
990 cell.select_all();
992 cell.select_all();
991 } else {
993 } else {
992 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
994 if ((cell_index === (that.ncells()-1)) && default_options.add_new) {
993 that.insert_cell_below('code');
995 that.insert_cell_below('code');
994 // If we are adding a new cell at the end, scroll down to show it.
996 // If we are adding a new cell at the end, scroll down to show it.
995 that.scroll_to_bottom();
997 that.scroll_to_bottom();
996 } else {
998 } else {
997 that.select(cell_index+1);
999 that.select(cell_index+1);
998 };
1000 };
999 };
1001 };
1000 this.dirty = true;
1002 this.dirty = true;
1001 };
1003 };
1002
1004
1003
1005
1004 Notebook.prototype.execute_all_cells = function () {
1006 Notebook.prototype.execute_all_cells = function () {
1005 var ncells = this.ncells();
1007 var ncells = this.ncells();
1006 for (var i=0; i<ncells; i++) {
1008 for (var i=0; i<ncells; i++) {
1007 this.select(i);
1009 this.select(i);
1008 this.execute_selected_cell({add_new:false});
1010 this.execute_selected_cell({add_new:false});
1009 };
1011 };
1010 this.scroll_to_bottom();
1012 this.scroll_to_bottom();
1011 };
1013 };
1012
1014
1013
1015
1014 Notebook.prototype.request_tool_tip = function (cell,func) {
1016 Notebook.prototype.request_tool_tip = function (cell,func) {
1015 // Feel free to shorten this logic if you are better
1017 // Feel free to shorten this logic if you are better
1016 // than me in regEx
1018 // than me in regEx
1017 // basicaly you shoul be able to get xxx.xxx.xxx from
1019 // basicaly you shoul be able to get xxx.xxx.xxx from
1018 // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
1020 // something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,
1019 // remove everything between matchin bracket (need to iterate)
1021 // remove everything between matchin bracket (need to iterate)
1020 matchBracket = /\([^\(\)]+\)/g;
1022 matchBracket = /\([^\(\)]+\)/g;
1021 oldfunc = func;
1023 oldfunc = func;
1022 func = func.replace(matchBracket,"");
1024 func = func.replace(matchBracket,"");
1023 while( oldfunc != func )
1025 while( oldfunc != func )
1024 {
1026 {
1025 oldfunc = func;
1027 oldfunc = func;
1026 func = func.replace(matchBracket,"");
1028 func = func.replace(matchBracket,"");
1027 }
1029 }
1028 // remove everythin after last open bracket
1030 // remove everythin after last open bracket
1029 endBracket = /\([^\(]*$/g;
1031 endBracket = /\([^\(]*$/g;
1030 func = func.replace(endBracket,"");
1032 func = func.replace(endBracket,"");
1031 var re = /[a-zA-Z._]+$/g;
1033 var re = /[a-zA-Z._]+$/g;
1032 var msg_id = this.kernel.object_info_request(re.exec(func));
1034 var msg_id = this.kernel.object_info_request(re.exec(func));
1033 if(typeof(msg_id)!='undefined'){
1035 if(typeof(msg_id)!='undefined'){
1034 this.msg_cell_map[msg_id] = cell.cell_id;
1036 this.msg_cell_map[msg_id] = cell.cell_id;
1035 }
1037 }
1036 };
1038 };
1037
1039
1038 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
1040 Notebook.prototype.complete_cell = function (cell, line, cursor_pos) {
1039 var msg_id = this.kernel.complete(line, cursor_pos);
1041 var msg_id = this.kernel.complete(line, cursor_pos);
1040 this.msg_cell_map[msg_id] = cell.cell_id;
1042 this.msg_cell_map[msg_id] = cell.cell_id;
1041 };
1043 };
1042
1044
1043 // Persistance and loading
1045 // Persistance and loading
1044
1046
1045
1047
1046 Notebook.prototype.fromJSON = function (data) {
1048 Notebook.prototype.fromJSON = function (data) {
1047 var ncells = this.ncells();
1049 var ncells = this.ncells();
1048 var i;
1050 var i;
1049 for (i=0; i<ncells; i++) {
1051 for (i=0; i<ncells; i++) {
1050 // Always delete cell 0 as they get renumbered as they are deleted.
1052 // Always delete cell 0 as they get renumbered as they are deleted.
1051 this.delete_cell(0);
1053 this.delete_cell(0);
1052 };
1054 };
1053 // Save the metadata
1055 // Save the metadata
1054 this.metadata = data.metadata;
1056 this.metadata = data.metadata;
1055 // Only handle 1 worksheet for now.
1057 // Only handle 1 worksheet for now.
1056 var worksheet = data.worksheets[0];
1058 var worksheet = data.worksheets[0];
1057 if (worksheet !== undefined) {
1059 if (worksheet !== undefined) {
1058 var new_cells = worksheet.cells;
1060 var new_cells = worksheet.cells;
1059 ncells = new_cells.length;
1061 ncells = new_cells.length;
1060 var cell_data = null;
1062 var cell_data = null;
1061 var new_cell = null;
1063 var new_cell = null;
1062 for (i=0; i<ncells; i++) {
1064 for (i=0; i<ncells; i++) {
1063 cell_data = new_cells[i];
1065 cell_data = new_cells[i];
1064 new_cell = this.insert_cell_below(cell_data.cell_type);
1066 new_cell = this.insert_cell_below(cell_data.cell_type);
1065 new_cell.fromJSON(cell_data);
1067 new_cell.fromJSON(cell_data);
1066 };
1068 };
1067 };
1069 };
1068 };
1070 };
1069
1071
1070
1072
1071 Notebook.prototype.toJSON = function () {
1073 Notebook.prototype.toJSON = function () {
1072 var cells = this.get_cells();
1074 var cells = this.get_cells();
1073 var ncells = cells.length;
1075 var ncells = cells.length;
1074 cell_array = new Array(ncells);
1076 cell_array = new Array(ncells);
1075 for (var i=0; i<ncells; i++) {
1077 for (var i=0; i<ncells; i++) {
1076 cell_array[i] = cells[i].toJSON();
1078 cell_array[i] = cells[i].toJSON();
1077 };
1079 };
1078 data = {
1080 data = {
1079 // Only handle 1 worksheet for now.
1081 // Only handle 1 worksheet for now.
1080 worksheets : [{cells:cell_array}],
1082 worksheets : [{cells:cell_array}],
1081 metadata : this.metadata
1083 metadata : this.metadata
1082 };
1084 };
1083 return data;
1085 return data;
1084 };
1086 };
1085
1087
1086 Notebook.prototype.save_notebook = function () {
1088 Notebook.prototype.save_notebook = function () {
1087 var notebook_id = IPython.save_widget.get_notebook_id();
1089 var notebook_id = IPython.save_widget.get_notebook_id();
1088 var nbname = IPython.save_widget.get_notebook_name();
1090 var nbname = IPython.save_widget.get_notebook_name();
1089 // We may want to move the name/id/nbformat logic inside toJSON?
1091 // We may want to move the name/id/nbformat logic inside toJSON?
1090 var data = this.toJSON();
1092 var data = this.toJSON();
1091 data.metadata.name = nbname;
1093 data.metadata.name = nbname;
1092 data.nbformat = 2;
1094 data.nbformat = 2;
1093 // We do the call with settings so we can set cache to false.
1095 // We do the call with settings so we can set cache to false.
1094 var settings = {
1096 var settings = {
1095 processData : false,
1097 processData : false,
1096 cache : false,
1098 cache : false,
1097 type : "PUT",
1099 type : "PUT",
1098 data : JSON.stringify(data),
1100 data : JSON.stringify(data),
1099 headers : {'Content-Type': 'application/json'},
1101 headers : {'Content-Type': 'application/json'},
1100 success : $.proxy(this.notebook_saved,this),
1102 success : $.proxy(this.notebook_saved,this),
1101 error : $.proxy(this.notebook_save_failed,this)
1103 error : $.proxy(this.notebook_save_failed,this)
1102 };
1104 };
1103 IPython.save_widget.status_saving();
1105 IPython.save_widget.status_saving();
1104 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1106 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1105 $.ajax(url, settings);
1107 $.ajax(url, settings);
1106 };
1108 };
1107
1109
1108
1110
1109 Notebook.prototype.notebook_saved = function (data, status, xhr) {
1111 Notebook.prototype.notebook_saved = function (data, status, xhr) {
1110 this.dirty = false;
1112 this.dirty = false;
1111 IPython.save_widget.notebook_saved();
1113 IPython.save_widget.notebook_saved();
1112 IPython.save_widget.status_last_saved();
1114 IPython.save_widget.status_last_saved();
1113 };
1115 };
1114
1116
1115
1117
1116 Notebook.prototype.notebook_save_failed = function (xhr, status, error_msg) {
1118 Notebook.prototype.notebook_save_failed = function (xhr, status, error_msg) {
1117 IPython.save_widget.status_save_failed();
1119 IPython.save_widget.status_save_failed();
1118 };
1120 };
1119
1121
1120
1122
1121 Notebook.prototype.load_notebook = function () {
1123 Notebook.prototype.load_notebook = function () {
1122 var that = this;
1124 var that = this;
1123 var notebook_id = IPython.save_widget.get_notebook_id();
1125 var notebook_id = IPython.save_widget.get_notebook_id();
1124 // We do the call with settings so we can set cache to false.
1126 // We do the call with settings so we can set cache to false.
1125 var settings = {
1127 var settings = {
1126 processData : false,
1128 processData : false,
1127 cache : false,
1129 cache : false,
1128 type : "GET",
1130 type : "GET",
1129 dataType : "json",
1131 dataType : "json",
1130 success : function (data, status, xhr) {
1132 success : function (data, status, xhr) {
1131 that.notebook_loaded(data, status, xhr);
1133 that.notebook_loaded(data, status, xhr);
1132 }
1134 }
1133 };
1135 };
1134 IPython.save_widget.status_loading();
1136 IPython.save_widget.status_loading();
1135 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1137 var url = $('body').data('baseProjectUrl') + 'notebooks/' + notebook_id;
1136 $.ajax(url, settings);
1138 $.ajax(url, settings);
1137 };
1139 };
1138
1140
1139
1141
1140 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
1142 Notebook.prototype.notebook_loaded = function (data, status, xhr) {
1141 this.fromJSON(data);
1143 this.fromJSON(data);
1142 if (this.ncells() === 0) {
1144 if (this.ncells() === 0) {
1143 this.insert_cell_below('code');
1145 this.insert_cell_below('code');
1144 };
1146 };
1145 IPython.save_widget.status_last_saved();
1147 IPython.save_widget.status_last_saved();
1146 IPython.save_widget.set_notebook_name(data.metadata.name);
1148 IPython.save_widget.set_notebook_name(data.metadata.name);
1147 this.dirty = false;
1149 this.dirty = false;
1148 if (! this.read_only) {
1150 if (! this.read_only) {
1149 this.start_kernel();
1151 this.start_kernel();
1150 }
1152 }
1151 this.select(0);
1153 this.select(0);
1152 this.scroll_to_top();
1154 this.scroll_to_top();
1153 IPython.save_widget.update_url();
1155 IPython.save_widget.update_url();
1154 IPython.layout_manager.do_resize();
1156 IPython.layout_manager.do_resize();
1155 };
1157 };
1156
1158
1157 IPython.Notebook = Notebook;
1159 IPython.Notebook = Notebook;
1158
1160
1159
1161
1160 return IPython;
1162 return IPython;
1161
1163
1162 }(IPython));
1164 }(IPython));
1163
1165
@@ -1,82 +1,102
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 // ToolBar
9 // ToolBar
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var ToolBar = function (selector) {
14 var ToolBar = function (selector) {
15 this.selector = selector;
15 this.selector = selector;
16 if (this.selector !== undefined) {
16 if (this.selector !== undefined) {
17 this.element = $(selector);
17 this.element = $(selector);
18 this.style();
18 this.style();
19 this.bind_events();
19 this.bind_events();
20 }
20 }
21 };
21 };
22
22
23
23
24 ToolBar.prototype.style = function () {
24 ToolBar.prototype.style = function () {
25 this.element.addClass('border-box-sizing');
25 this.element.addClass('border-box-sizing');
26 this.element.find('#cell_type').addClass('ui-widget ui-widget-content');
26 this.element.find('#save_b').button({
27 this.element.find('#save_b').button({
27 icons : {primary: 'ui-icon-disk'},
28 icons : {primary: 'ui-icon-disk'},
28 text : false
29 text : false
29 });
30 });
30 this.element.find('#cut_b').button({
31 this.element.find('#cut_b').button({
31 icons: {primary: 'ui-icon-scissors'},
32 icons: {primary: 'ui-icon-scissors'},
32 text : false
33 text : false
33 });
34 });
34 this.element.find('#copy_b').button({
35 this.element.find('#copy_b').button({
35 icons: {primary: 'ui-icon-copy'},
36 icons: {primary: 'ui-icon-copy'},
36 text : false
37 text : false
37 });
38 });
38 this.element.find('#paste_b').button({
39 this.element.find('#paste_b').button({
39 icons: {primary: 'ui-icon-clipboard'},
40 icons: {primary: 'ui-icon-clipboard'},
40 text : false
41 text : false
41 });
42 });
42 this.element.find('#cut_copy_paste').buttonset();
43 this.element.find('#cut_copy_paste').buttonset();
43 this.element.find('#move_up_b').button({
44 this.element.find('#move_up_b').button({
44 icons: {primary: 'ui-icon-arrowthick-1-n'},
45 icons: {primary: 'ui-icon-arrowthick-1-n'},
45 text : false
46 text : false
46 });
47 });
47 this.element.find('#move_down_b').button({
48 this.element.find('#move_down_b').button({
48 icons: {primary: 'ui-icon-arrowthick-1-s'},
49 icons: {primary: 'ui-icon-arrowthick-1-s'},
49 text : false
50 text : false
50 });
51 });
51 this.element.find('#move_up_down').buttonset();
52 this.element.find('#move_up_down').buttonset();
52 this.element.find('#insert_above_b').button({
53 this.element.find('#insert_above_b').button({
53 icons: {primary: 'ui-icon-arrowthickstop-1-n'},
54 icons: {primary: 'ui-icon-arrowthickstop-1-n'},
54 text : false
55 text : false
55 });
56 });
56 this.element.find('#insert_below_b').button({
57 this.element.find('#insert_below_b').button({
57 icons: {primary: 'ui-icon-arrowthickstop-1-s'},
58 icons: {primary: 'ui-icon-arrowthickstop-1-s'},
58 text : false
59 text : false
59 });
60 });
60 this.element.find('#insert_above_below').buttonset();
61 this.element.find('#insert_above_below').buttonset();
61 this.element.find('#run_b').button({
62 this.element.find('#run_b').button({
62 icons: {primary: 'ui-icon-play'},
63 icons: {primary: 'ui-icon-play'},
63 text : false
64 text : false
64 });
65 });
65 this.element.find('#interrupt_b').button({
66 this.element.find('#interrupt_b').button({
66 icons: {primary: 'ui-icon-stop'},
67 icons: {primary: 'ui-icon-stop'},
67 text : false
68 text : false
68 });
69 });
69 this.element.find('#run_int').buttonset();
70 this.element.find('#run_int').buttonset();
70 };
71 };
71
72
72
73
73 ToolBar.prototype.bind_events = function () {
74 ToolBar.prototype.bind_events = function () {
75 this.element.find('#cell_type').change(function () {
76 var cell_type = $(this).val();
77 if (cell_type === 'code') {
78 IPython.notebook.to_code();
79 } else if (cell_type === 'markdown') {
80 IPython.notebook.to_markdown();
81 };
82 });
83
84 };
85
86
87 ToolBar.prototype.set_cell_type = function (cell_type) {
88 this.element.find('#cell_type').val(cell_type);
89 };
90
74
91
92 ToolBar.prototype.toggle = function () {
93 this.element.toggle();
94 IPython.layout_manager.do_resize();
75 };
95 };
76
96
77
97
78 IPython.ToolBar = ToolBar;
98 IPython.ToolBar = ToolBar;
79
99
80 return IPython;
100 return IPython;
81
101
82 }(IPython));
102 }(IPython));
@@ -1,221 +1,227
1 <!DOCTYPE HTML>
1 <!DOCTYPE HTML>
2 <html>
2 <html>
3
3
4 <head>
4 <head>
5 <meta charset="utf-8">
5 <meta charset="utf-8">
6
6
7 <title>IPython Notebook</title>
7 <title>IPython Notebook</title>
8
8
9 {% if mathjax_url %}
9 {% if mathjax_url %}
10 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
10 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
11 {% end %}
11 {% end %}
12 <script type="text/javascript">
12 <script type="text/javascript">
13 // MathJax disabled, set as null to distingish from *missing* MathJax,
13 // MathJax disabled, set as null to distingish from *missing* MathJax,
14 // where it will be undefined, and should prompt a dialog later.
14 // where it will be undefined, and should prompt a dialog later.
15 window.mathjax_url = "{{mathjax_url}}";
15 window.mathjax_url = "{{mathjax_url}}";
16 </script>
16 </script>
17
17
18 <link rel="stylesheet" href="/static/jquery/css/themes/base/jquery-ui.min.css" type="text/css" />
18 <link rel="stylesheet" href="/static/jquery/css/themes/base/jquery-ui.min.css" type="text/css" />
19 <link rel="stylesheet" href="/static/codemirror/lib/codemirror.css">
19 <link rel="stylesheet" href="/static/codemirror/lib/codemirror.css">
20 <link rel="stylesheet" href="/static/codemirror/theme/ipython.css">
20 <link rel="stylesheet" href="/static/codemirror/theme/ipython.css">
21
21
22 <link rel="stylesheet" href="/static/prettify/prettify.css"/>
22 <link rel="stylesheet" href="/static/prettify/prettify.css"/>
23
23
24 <link rel="stylesheet" href="/static/css/boilerplate.css" type="text/css" />
24 <link rel="stylesheet" href="/static/css/boilerplate.css" type="text/css" />
25 <link rel="stylesheet" href="/static/css/layout.css" type="text/css" />
25 <link rel="stylesheet" href="/static/css/layout.css" type="text/css" />
26 <link rel="stylesheet" href="/static/css/base.css" type="text/css" />
26 <link rel="stylesheet" href="/static/css/base.css" type="text/css" />
27 <link rel="stylesheet" href="/static/css/notebook.css" type="text/css" />
27 <link rel="stylesheet" href="/static/css/notebook.css" type="text/css" />
28 <link rel="stylesheet" href="/static/css/renderedhtml.css" type="text/css" />
28 <link rel="stylesheet" href="/static/css/renderedhtml.css" type="text/css" />
29
29
30 {% comment In the notebook, the read-only flag is used to determine %}
30 {% comment In the notebook, the read-only flag is used to determine %}
31 {% comment whether to hide the side panels and switch off input %}
31 {% comment whether to hide the side panels and switch off input %}
32 <meta name="read_only" content="{{read_only and not logged_in}}"/>
32 <meta name="read_only" content="{{read_only and not logged_in}}"/>
33
33
34 </head>
34 </head>
35
35
36 <body
36 <body
37 data-project={{project}} data-notebook-id={{notebook_id}}
37 data-project={{project}} data-notebook-id={{notebook_id}}
38 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
38 data-base-project-url={{base_project_url}} data-base-kernel-url={{base_kernel_url}}
39 >
39 >
40
40
41 <div id="header">
41 <div id="header">
42 <span id="ipython_notebook"><h1><a href='..' alt='dashboard'><img src='/static/ipynblogo.png' alt='IPython Notebook'/></a></h1></span>
42 <span id="ipython_notebook"><h1><a href='..' alt='dashboard'><img src='/static/ipynblogo.png' alt='IPython Notebook'/></a></h1></span>
43 <span id="save_widget">
43 <span id="save_widget">
44 <span id="notebook_name"></span>
44 <span id="notebook_name"></span>
45 <span id="save_status"></span>
45 <span id="save_status"></span>
46 </span>
46 </span>
47
47
48 <span id="login_widget">
48 <span id="login_widget">
49 {% comment This is a temporary workaround to hide the logout button %}
49 {% comment This is a temporary workaround to hide the logout button %}
50 {% comment when appropriate until notebook.html is templated %}
50 {% comment when appropriate until notebook.html is templated %}
51 {% if logged_in %}
51 {% if logged_in %}
52 <button id="logout">Logout</button>
52 <button id="logout">Logout</button>
53 {% elif not logged_in and login_available %}
53 {% elif not logged_in and login_available %}
54 <button id="login">Login</button>
54 <button id="login">Login</button>
55 {% end %}
55 {% end %}
56 </span>
56 </span>
57
57
58 <span id="kernel_status">Idle</span>
58 <span id="kernel_status">Idle</span>
59 </div>
59 </div>
60
60
61 <div id="menubar">
61 <div id="menubar">
62 <ul id="menus">
62 <ul id="menus">
63 <li><a href="#">File</a>
63 <li><a href="#">File</a>
64 <ul>
64 <ul>
65 <li id="new_notebook"><a href="#">New</a></li>
65 <li id="new_notebook"><a href="#">New</a></li>
66 <li id="open_notebook"><a href="#">Open...</a></li>
66 <li id="open_notebook"><a href="#">Open...</a></li>
67 <hr/>
67 <hr/>
68 <li id="copy_notebook"><a href="#">Make a Copy...</a></li>
68 <li id="copy_notebook"><a href="#">Make a Copy...</a></li>
69 <li id="rename_notebook"><a href="#">Rename...</a></li>
69 <li id="rename_notebook"><a href="#">Rename...</a></li>
70 <li id="save_notebook"><a href="#">Save</a></li>
70 <li id="save_notebook"><a href="#">Save</a></li>
71 <hr/>
71 <hr/>
72 <li><a href="#">Download as</a>
72 <li><a href="#">Download as</a>
73 <ul>
73 <ul>
74 <li id="download_ipynb"><a href="#">IPython (.ipynb)</a></li>
74 <li id="download_ipynb"><a href="#">IPython (.ipynb)</a></li>
75 <li id="download_py"><a href="#">Python (.py)</a></li>
75 <li id="download_py"><a href="#">Python (.py)</a></li>
76 </ul>
76 </ul>
77 </li>
77 </li>
78 <hr/>
78 <hr/>
79 <li id="print_notebook"><a href="/{{notebook_id}}/print" target="_blank">Print View</a></li>
79 <li id="print_notebook"><a href="/{{notebook_id}}/print" target="_blank">Print View</a></li>
80 </ul>
80 </ul>
81 </li>
81 </li>
82 <li><a href="#">Edit</a>
82 <li><a href="#">Edit</a>
83 <ul>
83 <ul>
84 <li id="cut_cell"><a href="#">Cut</a></li>
84 <li id="cut_cell"><a href="#">Cut</a></li>
85 <li id="copy_cell"><a href="#">Copy</a></li>
85 <li id="copy_cell"><a href="#">Copy</a></li>
86 <li id="paste_cell" class="ui-state-disabled"><a href="#">Paste</a></li>
86 <li id="paste_cell" class="ui-state-disabled"><a href="#">Paste</a></li>
87 <li id="paste_cell_above" class="ui-state-disabled"><a href="#">Paste Above</a></li>
87 <li id="paste_cell_above" class="ui-state-disabled"><a href="#">Paste Above</a></li>
88 <li id="paste_cell_below" class="ui-state-disabled"><a href="#">Paste Below</a></li>
88 <li id="paste_cell_below" class="ui-state-disabled"><a href="#">Paste Below</a></li>
89 <li id="delete_cell"><a href="#">Delete</a></li>
89 <li id="delete_cell"><a href="#">Delete</a></li>
90 <hr/>
90 <hr/>
91 <li id="split_cell"><a href="#">Split</a></li>
91 <li id="split_cell"><a href="#">Split</a></li>
92 <li id="merge_cell_above"><a href="#">Merge Above</a></li>
92 <li id="merge_cell_above"><a href="#">Merge Above</a></li>
93 <li id="merge_cell_below"><a href="#">Merge Below</a></li>
93 <li id="merge_cell_below"><a href="#">Merge Below</a></li>
94 <hr/>
94 <hr/>
95 <li id="move_cell_up"><a href="#">Move Up</a></li>
95 <li id="move_cell_up"><a href="#">Move Up</a></li>
96 <li id="move_cell_down"><a href="#">Move Down</a></li>
96 <li id="move_cell_down"><a href="#">Move Down</a></li>
97 <hr/>
97 <hr/>
98 <li id="select_previous"><a href="#">Select Previous</a></li>
98 <li id="select_previous"><a href="#">Select Previous</a></li>
99 <li id="select_next"><a href="#">Select Next</a></li>
99 <li id="select_next"><a href="#">Select Next</a></li>
100 </ul>
100 </ul>
101 </li>
101 </li>
102 <li><a href="#">View</a>
103 <ul>
104 <li id="toggle_header"><a href="#">Toggle Header</a></li>
105 <li id="toggle_toolbar"><a href="#">Toggle Toolbar</a></li>
106 </ul>
107 </li>
102 <li><a href="#">Insert</a>
108 <li><a href="#">Insert</a>
103 <ul>
109 <ul>
104 <li id="insert_cell_above"><a href="#">Insert Cell Above</a></li>
110 <li id="insert_cell_above"><a href="#">Insert Cell Above</a></li>
105 <li id="insert_cell_below"><a href="#">Insert Cell Below</a></li>
111 <li id="insert_cell_below"><a href="#">Insert Cell Below</a></li>
106 </ul>
112 </ul>
107 </li>
113 </li>
108 <li><a href="#">Cell</a>
114 <li><a href="#">Cell</a>
109 <ul>
115 <ul>
110 <li id="run_cell"><a href="#">Run</a></li>
116 <li id="run_cell"><a href="#">Run</a></li>
111 <li id="run_cell_in_place"><a href="#">Run in Place</a></li>
117 <li id="run_cell_in_place"><a href="#">Run in Place</a></li>
112 <li id="run_all_cells"><a href="#">Run All</a></li>
118 <li id="run_all_cells"><a href="#">Run All</a></li>
113 <hr/>
119 <hr/>
114 <li id="to_code"><a href="#">Code Cell</a></li>
120 <li id="to_code"><a href="#">Code Cell</a></li>
115 <li id="to_markdown"><a href="#">Markdown Cell</a></li>
121 <li id="to_markdown"><a href="#">Markdown Cell</a></li>
116 <hr/>
122 <hr/>
117 <li id="toggle_output"><a href="#">Toggle Output</a></li>
123 <li id="toggle_output"><a href="#">Toggle Output</a></li>
118 <li id="clear_all_output"><a href="#">Clear All Output</a></li>
124 <li id="clear_all_output"><a href="#">Clear All Output</a></li>
119 </ul>
125 </ul>
120 </li>
126 </li>
121 <li><a href="#">Kernel</a>
127 <li><a href="#">Kernel</a>
122 <ul>
128 <ul>
123 <li id="int_kernel"><a href="#">Interrupt</a></li>
129 <li id="int_kernel"><a href="#">Interrupt</a></li>
124 <li id="restart_kernel"><a href="#">Restart</a></li>
130 <li id="restart_kernel"><a href="#">Restart</a></li>
125 </ul>
131 </ul>
126 </li>
132 </li>
127 <li><a href="#">Help</a>
133 <li><a href="#">Help</a>
128 <ul>
134 <ul>
129 <li><a href="http://ipython.org/documentation.html" target="_blank">IPython Help</a></li>
135 <li><a href="http://ipython.org/documentation.html" target="_blank">IPython Help</a></li>
130 <li><a href="http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html" target="_blank">Notebook Help</a></li>
136 <li><a href="http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html" target="_blank">Notebook Help</a></li>
131 <li id="keyboard_shortcuts"><a href="#">Keyboard Shortcuts</a></li>
137 <li id="keyboard_shortcuts"><a href="#">Keyboard Shortcuts</a></li>
132 <hr/>
138 <hr/>
133 <li><a href="http://docs.python.org" target="_blank">Python</a></li>
139 <li><a href="http://docs.python.org" target="_blank">Python</a></li>
134 <li><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></li>
140 <li><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></li>
135 <li><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></li>
141 <li><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></li>
136 <li><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></li>
142 <li><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></li>
137 <li><a href="http://matplotlib.sourceforge.net/" target="_blank">Matplotlib</a></li>
143 <li><a href="http://matplotlib.sourceforge.net/" target="_blank">Matplotlib</a></li>
138 </ul>
144 </ul>
139 </li>
145 </li>
140 </ul>
146 </ul>
141
147
142 </div>
148 </div>
143
149
144 <div id="toolbar">
150 <div id="toolbar">
145
151
146 <span>
152 <span>
147 <button id="save_b">Save</button>
153 <button id="save_b">Save</button>
148 </span>
154 </span>
149 <span id="cut_copy_paste">
155 <span id="cut_copy_paste">
150 <button id="cut_b" title="Cut">Cut</button>
156 <button id="cut_b" title="Cut">Cut</button>
151 <button id="copy_b" title="Copy">Copy</button>
157 <button id="copy_b" title="Copy">Copy</button>
152 <button id="paste_b" title="Paste">Paste</button>
158 <button id="paste_b" title="Paste">Paste</button>
153 </span>
159 </span>
154 <span id="move_up_down">
160 <span id="move_up_down">
155 <button id="move_up_b" title="Move Up">Move Up</button>
161 <button id="move_up_b" title="Move Up">Move Up</button>
156 <button id="move_down_b" title="Move Down">Move Down</button>
162 <button id="move_down_b" title="Move Down">Move Down</button>
157 </span>
163 </span>
158 <span id="insert_above_below">
164 <span id="insert_above_below">
159 <button id="insert_above_b" title="Insert Above">Insert Above</button>
165 <button id="insert_above_b" title="Insert Above">Insert Above</button>
160 <button id="insert_below_b" title="Insert Below">Insert Below</button>
166 <button id="insert_below_b" title="Insert Below">Insert Below</button>
161 </span>
167 </span>
162 <span id="run_int">
168 <span id="run_int">
163 <button id="run_b" title="Run">Run</button>
169 <button id="run_b" title="Run">Run</button>
164 <button id="interrupt_b" title="Interrupt">Interrupt</button>
170 <button id="interrupt_b" title="Interrupt">Interrupt</button>
165 </span>
171 </span>
166 <span>
172 <span>
167 <select id="cell_type">
173 <select id="cell_type">
168 <option value="code">Code</option>
174 <option value="code">Code</option>
169 <option value="markdown">Markdown</option>
175 <option value="markdown">Markdown</option>
170 </select>
176 </select>
171 </span>
177 </span>
172
178
173 </div>
179 </div>
174
180
175 <div id="main_app">
181 <div id="main_app">
176
182
177 <div id="notebook_panel">
183 <div id="notebook_panel">
178 <div id="notebook"></div>
184 <div id="notebook"></div>
179 <div id="pager_splitter"></div>
185 <div id="pager_splitter"></div>
180 <div id="pager"></div>
186 <div id="pager"></div>
181 </div>
187 </div>
182
188
183 </div>
189 </div>
184
190
185 <script src="/static/jquery/js/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
191 <script src="/static/jquery/js/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
186 <script src="/static/jquery/js/jquery-ui.min.js" type="text/javascript" charset="utf-8"></script>
192 <script src="/static/jquery/js/jquery-ui.min.js" type="text/javascript" charset="utf-8"></script>
187
193
188 <script src="/static/codemirror/lib/codemirror.js" charset="utf-8"></script>
194 <script src="/static/codemirror/lib/codemirror.js" charset="utf-8"></script>
189 <script src="/static/codemirror/mode/python/python.js" charset="utf-8"></script>
195 <script src="/static/codemirror/mode/python/python.js" charset="utf-8"></script>
190 <script src="/static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
196 <script src="/static/codemirror/mode/htmlmixed/htmlmixed.js" charset="utf-8"></script>
191 <script src="/static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
197 <script src="/static/codemirror/mode/xml/xml.js" charset="utf-8"></script>
192 <script src="/static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
198 <script src="/static/codemirror/mode/javascript/javascript.js" charset="utf-8"></script>
193 <script src="/static/codemirror/mode/css/css.js" charset="utf-8"></script>
199 <script src="/static/codemirror/mode/css/css.js" charset="utf-8"></script>
194 <script src="/static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
200 <script src="/static/codemirror/mode/rst/rst.js" charset="utf-8"></script>
195 <script src="/static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
201 <script src="/static/codemirror/mode/markdown/markdown.js" charset="utf-8"></script>
196
202
197 <script src="/static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
203 <script src="/static/pagedown/Markdown.Converter.js" charset="utf-8"></script>
198
204
199 <script src="/static/prettify/prettify.js" charset="utf-8"></script>
205 <script src="/static/prettify/prettify.js" charset="utf-8"></script>
200 <script src="/static/dateformat/date.format.js" charset="utf-8"></script>
206 <script src="/static/dateformat/date.format.js" charset="utf-8"></script>
201
207
202 <script src="/static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
208 <script src="/static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
203 <script src="/static/js/utils.js" type="text/javascript" charset="utf-8"></script>
209 <script src="/static/js/utils.js" type="text/javascript" charset="utf-8"></script>
204 <script src="/static/js/cell.js" type="text/javascript" charset="utf-8"></script>
210 <script src="/static/js/cell.js" type="text/javascript" charset="utf-8"></script>
205 <script src="/static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
211 <script src="/static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
206 <script src="/static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
212 <script src="/static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
207 <script src="/static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
213 <script src="/static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
208 <script src="/static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
214 <script src="/static/js/kernelstatus.js" type="text/javascript" charset="utf-8"></script>
209 <script src="/static/js/layout.js" type="text/javascript" charset="utf-8"></script>
215 <script src="/static/js/layout.js" type="text/javascript" charset="utf-8"></script>
210 <script src="/static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
216 <script src="/static/js/savewidget.js" type="text/javascript" charset="utf-8"></script>
211 <script src="/static/js/quickhelp.js" type="text/javascript" charset="utf-8"></script>
217 <script src="/static/js/quickhelp.js" type="text/javascript" charset="utf-8"></script>
212 <script src="/static/js/loginwidget.js" type="text/javascript" charset="utf-8"></script>
218 <script src="/static/js/loginwidget.js" type="text/javascript" charset="utf-8"></script>
213 <script src="/static/js/pager.js" type="text/javascript" charset="utf-8"></script>
219 <script src="/static/js/pager.js" type="text/javascript" charset="utf-8"></script>
214 <script src="/static/js/menubar.js" type="text/javascript" charset="utf-8"></script>
220 <script src="/static/js/menubar.js" type="text/javascript" charset="utf-8"></script>
215 <script src="/static/js/toolbar.js" type="text/javascript" charset="utf-8"></script>
221 <script src="/static/js/toolbar.js" type="text/javascript" charset="utf-8"></script>
216 <script src="/static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
222 <script src="/static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
217 <script src="/static/js/notebookmain.js" type="text/javascript" charset="utf-8"></script>
223 <script src="/static/js/notebookmain.js" type="text/javascript" charset="utf-8"></script>
218
224
219 </body>
225 </body>
220
226
221 </html>
227 </html>
General Comments 0
You need to be logged in to leave comments. Login now