##// END OF EJS Templates
Initial draft of panel section and the cell section working.
Brian E. Granger -
Show More
@@ -0,0 +1,214 b''
1
2 //============================================================================
3 // Cell
4 //============================================================================
5
6 var IPython = (function (IPython) {
7
8 var utils = IPython.utils;
9
10 // Base PanelSection class
11
12 var PanelSection = function () {
13 if (this.section_name === undefined) {
14 this.section_name = 'section';
15 };
16 this.create_element();
17 if (this.element !== undefined) {
18 this.bind_events();
19 }
20 this.expanded = true;
21 };
22
23
24 PanelSection.prototype.bind_events = function () {
25 var that = this;
26 this.header.click(function () {
27 that.toggle();
28 });
29 this.header.hover(function () {
30 that.header.toggleClass('ui-state-hover');
31 });
32 };
33
34
35 PanelSection.prototype.create_element = function () {
36 this.element = $('<div/>').attr('id',this.id());
37 this.header = $('<h3>'+this.section_name+'</h3>').
38 addClass('ui-widget ui-state-default section_header');
39 this.content = $('<div/>').
40 addClass('ui-widget section_content');
41 this.element.append(this.header).append(this.content);
42 this.create_children();
43 };
44
45
46 PanelSection.prototype.id = function () {
47 return this.section_name.toLowerCase() + "_section";
48 };
49
50
51 PanelSection.prototype.expand = function () {
52 if (!this.expanded) {
53 this.content.slideDown('fast');
54 // this.header.addClass('ui-state-active');
55 // this.header.removeClass('ui-state-default');
56 this.expanded = true;
57 };
58 };
59
60
61 PanelSection.prototype.collapse = function () {
62 if (this.expanded) {
63 this.content.slideUp('fast');
64 // this.header.removeClass('ui-state-active');
65 // this.header.addClass('ui-state-default');
66 this.expanded = false;
67 };
68 };
69
70
71 PanelSection.prototype.toggle = function () {
72 if (this.expanded === true) {
73 this.collapse();
74 } else {
75 this.expand();
76 };
77 };
78
79
80 PanelSection.prototype.create_children = function () {};
81
82
83 // NotebookSection
84
85 var NotebookSection = function () {
86 this.section_name = "Notebook";
87 PanelSection.apply(this, arguments);
88 };
89
90
91 NotebookSection.prototype = new PanelSection();
92
93
94 // CellSection
95
96 var CellSection = function () {
97 this.section_name = "Cell";
98 PanelSection.apply(this, arguments);
99 };
100
101
102 CellSection.prototype = new PanelSection();
103
104
105 CellSection.prototype.bind_events = function () {
106 PanelSection.prototype.bind_events.apply(this);
107 this.content.find('#collapse_cell').click(function () {
108 IPython.notebook.collapse();
109 });
110 this.content.find('#expand_cell').click(function () {
111 IPython.notebook.expand();
112 });
113 this.content.find('#delete_cell').click(function () {
114 IPython.notebook.delete_cell();
115 });
116 this.content.find('#insert_cell_above').click(function () {
117 IPython.notebook.insert_code_cell_before();
118 });
119 this.content.find('#insert_cell_below').click(function () {
120 IPython.notebook.insert_code_cell_after();
121 });
122 this.content.find('#move_cell_up').click(function () {
123 IPython.notebook.move_cell_up();
124 });
125 this.content.find('#move_cell_down').click(function () {
126 IPython.notebook.move_cell_down();
127 });
128 this.content.find('#to_code').click(function () {
129 IPython.notebook.text_to_code();
130 });
131 this.content.find('#to_text').click(function () {
132 IPython.notebook.code_to_text();
133 });
134 };
135
136
137 CellSection.prototype.create_children = function () {
138 var row0 = $('<div>').
139 append($('<span/>').attr('id','toggle').
140 append( $('<button>Collapse</button>').attr('id','collapse_cell') ).
141 append( $('<button>Expand</button>').attr('id','expand_cell') ) ).
142 append($('<span/>').
143 append($('<button>X</button>').attr('id','delete_cell')));
144 row0.find('#toggle').buttonset();
145 row0.find('button#delete_cell').button();
146 this.content.append(row0);
147
148 var row1 = $('<div>').
149 append($('<span/>').html('Insert').addClass('button_label')).
150 append($('<span/>').attr('id','insert').
151 append( $('<button>Above</button>').attr('id','insert_cell_above') ).
152 append( $('<button>Below</button>').attr('id','insert_cell_below') ) );
153 row1.find('#insert').buttonset();
154 this.content.append(row1);
155
156 var row2 = $('<div>').
157 append($('<span/>').html('Move').addClass('button_label')).
158 append($('<span/>').attr('id','move').
159 append( $('<button>Up</button>').attr('id','move_cell_up') ).
160 append( $('<button>Down</button>').attr('id','move_cell_down') ) );
161 row2.find('#move').buttonset();
162 this.content.append(row2);
163
164 var row3 = $('<div>').
165 append($('<span/>').html('Cell Type').addClass('button_label')).
166 append($('<span/>').attr('id','cell_type').
167 append( $('<button>Code</button>').attr('id','to_code') ).
168 append( $('<button>Text</button>').attr('id','to_text') ) );
169 row3.find('#cell_type').buttonset();
170 this.content.append(row3)
171 };
172 // <span id="move_cell">
173 // <button id="move_up">Move up</button>
174 // <button id="move_down">Move down</button>
175 // </span>
176 // <span id="insert_delete">
177 // <button id="insert_cell_before">Before</button>
178 // <button id="insert_cell_after">After</button>
179 // <button id="delete_cell">Delete</button>
180 // </span>
181 // <span id="cell_type">
182 // <button id="to_code">Code</button>
183 // <button id="to_text">Text</button>
184 // </span>
185 // <span id="sort">
186 // <button id="sort_cells">Sort</button>
187 // </span>
188 // <span id="toggle">
189 // <button id="collapse">Collapse</button>
190 // <button id="expand">Expand</button>
191 // </span>
192 // </span>
193
194
195 // KernelSection
196
197 var KernelSection = function () {
198 this.section_name = "Kernel";
199 PanelSection.apply(this, arguments);
200 };
201
202
203 KernelSection.prototype = new PanelSection();
204
205
206 IPython.PanelSection = PanelSection;
207 IPython.NotebookSection = NotebookSection;
208 IPython.CellSection = CellSection;
209 IPython.KernelSection = KernelSection;
210
211 return IPython;
212
213 }(IPython));
214
@@ -1,248 +1,267 b''
1 1 /**
2 2 * HTML5 ✰ Boilerplate
3 3 *
4 4 * style.css contains a reset, font normalization and some base styles.
5 5 *
6 6 * Credit is left where credit is due.
7 7 * Much inspiration was taken from these projects:
8 8 * - yui.yahooapis.com/2.8.1/build/base/base.css
9 9 * - camendesign.com/design/
10 10 * - praegnanz.de/weblog/htmlcssjs-kickstart
11 11 */
12 12
13 13
14 14 /**
15 15 * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
16 16 * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
17 17 * html5doctor.com/html-5-reset-stylesheet/
18 18 */
19 19
20 20 html, body, div, span, object, iframe,
21 21 h1, h2, h3, h4, h5, h6, p, blockquote, pre,
22 22 abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
23 23 small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
24 24 fieldset, form, label, legend,
25 25 table, caption, tbody, tfoot, thead, tr, th, td,
26 26 article, aside, canvas, details, figcaption, figure,
27 27 footer, header, hgroup, menu, nav, section, summary,
28 28 time, mark, audio, video {
29 29 margin: 0;
30 30 padding: 0;
31 31 border: 0;
32 32 /* font-size: 100%;*/
33 33 font: inherit;
34 34 vertical-align: baseline;
35 35 }
36 36
37 37 article, aside, details, figcaption, figure,
38 38 footer, header, hgroup, menu, nav, section {
39 39 display: block;
40 40 }
41 41
42 42 blockquote, q { quotes: none; }
43 43
44 44 blockquote:before, blockquote:after,
45 45 q:before, q:after { content: ""; content: none; }
46 46
47 47 ins { background-color: #ff9; color: #000; text-decoration: none; }
48 48
49 49 mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
50 50
51 51 del { text-decoration: line-through; }
52 52
53 53 abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
54 54
55 55 table { border-collapse: collapse; border-spacing: 0; }
56 56
57 57 hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
58 58
59 59 input, select { vertical-align: middle; }
60 60
61 61 body {
62 62 background-color: white;
63 63 /* This won't propagate to all children so we also set it below */
64 64 font-size: 10pt;
65 65 /* This makes sure that the body covers the entire window and needs to
66 66 be in a different element than the display: box in wrapper below */
67 67 position: absolute;
68 68 left: 0px;
69 69 right: 0px;
70 70 top: 0px;
71 71 bottom: 0px;
72 72 overflow: hidden;
73 73 }
74 74
75 75
76 76 span#ipython_notebook h1 {
77 77 font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
78 78 font-size: 22pt;
79 79 height: 35px;
80 80 padding: 5px;
81 81 margin: 0px;
82 82
83 83 }
84 84
85 85 span#kernel_status {
86 86 position: absolute;
87 87 top: 12%;
88 88 right: 10px;
89 89 font-weight: bold;
90 90 }
91 91
92 92 .status_idle {
93 93 color: gray;
94 94 }
95 95
96 96 .status_busy {
97 97 color: red;
98 98 }
99 99
100 100 .status_restarting {
101 101 color: black;
102 102 }
103 103
104 104 div#notebook_app {
105 105 width: 100%;
106 106 position: relative;
107 107 }
108 108
109 109 div#left_panel {
110 110 overflow-y: auto;
111 111 top: 0px;
112 112 left: 0px;
113 113 margin: 0px;
114 114 padding: 0px;
115 115 position: absolute;
116 116 }
117 117
118 h3.section_header {
119 padding: 5px;
120 }
121
122 div.section_content {
123 padding: 5px;
124 }
125
126
127 span.button_label {
128 padding: 0.3em 1em;
129 font-size: 0.8em;
130 }
131
132 .ui-button .ui-button-text {
133 padding: 0.3em 0.9em;
134 font-size: 0.7em;
135 }
136
118 137 div#left_panel_splitter {
119 138 width: 8px;
120 139 top: 0px;
121 140 left: 202px;
122 141 margin: 0px;
123 142 padding: 0px;
124 143 position: absolute;
125 144 }
126 145
127 146 div#notebook_panel {
128 147 /* The L margin will be set in the Javascript code*/
129 148 margin: 0px 0px 0px 0px;
130 149 padding: 0px;
131 150 }
132 151
133 152 div#notebook {
134 153 overflow-y: scroll;
135 154 overflow-x: auto;
136 155 width: 100%;
137 156 padding: 0px 15px 0px 15px;
138 157 margin: 0px
139 158 background-color: white;
140 159 font-size: 10pt;
141 160 }
142 161
143 162 div#pager_splitter {
144 163 height: 8px;
145 164 }
146 165
147 166 div#pager {
148 167 padding: 15px;
149 168 overflow: auto;
150 169 }
151 170
152 171 .monospace-font {
153 172 font-family: monospace;
154 173 font-size: 10pt;
155 174 }
156 175
157 176 div.cell {
158 177 width: 100%;
159 178 padding: 5px;
160 179 /* This acts as a spacer between cells, that is outside the border */
161 180 margin: 15px 0px 15px 0px;
162 181 }
163 182
164 183 div.code_cell {
165 184 background-color: white;
166 185 }
167 186
168 187 div.prompt {
169 188 width: 90px;
170 189 padding: 0px;
171 190 margin: 0px;
172 191 }
173 192
174 193 div.input_prompt {
175 194 color: navy;
176 195 }
177 196
178 197 div.output {
179 198 /* This is a spacer between the input and output of each cell */
180 199 margin-top: 15px;
181 200 }
182 201
183 202 div.output_prompt {
184 203 color: darkred;
185 204 }
186 205
187 206 div.output_area {
188 207 text-align: left;
189 208 color: black;
190 209 }
191 210
192 211 div.output_latex {
193 212 /* Slightly bigger than the rest of the notebook */
194 213 font-size: 11pt;
195 214 }
196 215
197 216 div.output_png {
198 217 }
199 218
200 219 div.text_cell {
201 220 background-color: white;
202 221 }
203 222
204 223 textarea.text_cell_input {
205 224 /* Slightly bigger than the rest of the notebook */
206 225 font-size: 11pt;
207 226 outline: none;
208 227 resize: none;
209 228 width: inherit;
210 229 border-style: none;
211 230 padding: 0px;
212 231 margin: 0px;
213 232 color: black;
214 233 }
215 234
216 235 div.text_cell_render {
217 236 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
218 237 /* Slightly bigger than the rest of the notebook */
219 238 font-size: 11pt;
220 239 outline: none;
221 240 resize: none;
222 241 width: inherit;
223 242 border-style: none;
224 243 padding: 5px;
225 244 color: black;
226 245 }
227 246
228 247 div.text_cell_render em {font-style: italic;}
229 248 div.text_cell_render strong {font-weight: bold;}
230 249 div.text_cell_render u {text-decoration: underline;}
231 250 div.text_cell_render :link { text-decoration: underline }
232 251 div.text_cell_render :visited { text-decoration: underline }
233 252 div.text_cell_render h1 {font-size: 2.0em; margin: .67em 0; font-weight: bold;}
234 253 div.text_cell_render h2 {font-size: 1.5em; margin: .75em 0; font-weight: bold;}
235 254 div.text_cell_render h3 {font-size: 1.17em; margin: .83em 0; font-weight: bold;}
236 255 div.text_cell_render h4 {margin: 1.12em 0; font-weight: bold;}
237 256 div.text_cell_render h5 {font-size: .83em; margin: 1.5em 0; font-weight: bold;}
238 257 div.text_cell_render h6 {font-size: .75em; margin: 1.67em 0; font-weight: bold;}
239 258 div.text_cell_render ul {list-style:disc; margin-left: 40px;}
240 259 div.text_cell_render ul ul {list-style:square; margin-left: 40px;}
241 260 div.text_cell_render ul ul ul {list-style:circle; margin-left: 40px;}
242 261 div.text_cell_render ol {list-style:upper-roman; margin-left: 40px;}
243 262 div.text_cell_render ol ol {list-style:upper-alpha;}
244 263 div.text_cell_render ol ol ol {list-style:decimal;}
245 264 div.text_cell_render ol ol ol ol {list-style:lower-alpha;}
246 265 div.text_cell_render ol ol ol ol ol {list-style:lower-roman;}
247 266
248 267
@@ -1,56 +1,55 b''
1 1
2 2 //============================================================================
3 3 // Layout
4 4 //============================================================================
5 5
6 6 var IPython = (function (IPython) {
7 7
8 8 var LayoutManager = function () {
9 9 this.bind_events();
10 10 };
11 11
12 12
13 13 LayoutManager.prototype.bind_events = function () {
14 14 $(window).resize($.proxy(this.do_resize,this));
15 15 };
16 16
17 17
18 18 LayoutManager.prototype.do_resize = function () {
19 19 var win = $(window);
20 20 var w = win.width();
21 21 var h = win.height();
22 22 var header_height = $('div#header').outerHeight(true);
23 23 var app_height = h - header_height - 2; // content height
24 24
25 25 $('div#notebook_app').height(app_height + 2); // content+padding+border height
26 26
27 27 $('div#left_panel').height(app_height);
28 28
29 29 $('div#left_panel_splitter').height(app_height);
30 30
31 31 var left_panel_width = $('div#left_panel').outerWidth();
32 32 var left_panel_splitter_width = $('div#left_panel_splitter').outerWidth();
33 33 $('div#notebook_panel').height(app_height);
34 34 if (IPython.left_panel.expanded) {
35 35 $('div#notebook_panel').css({marginLeft : left_panel_width+left_panel_splitter_width});
36 36 } else {
37 37 $('div#notebook_panel').css({marginLeft : left_panel_splitter_width});
38 38 }
39 39
40 40
41 41 var pager_height = IPython.pager.percentage_height*app_height;
42 42 var pager_splitter_height = $('div#pager_splitter').outerHeight(true);
43 43 $('div#pager').height(pager_height);
44 44 if (IPython.pager.expanded) {
45 45 $('div#notebook').height(app_height-pager_height-pager_splitter_height);
46 46 } else {
47 47 $('div#notebook').height(app_height-pager_splitter_height);
48 48 }
49 console.log('resize: ', app_height);
50 49 };
51 50
52 51 IPython.LayoutManager = LayoutManager
53 52
54 53 return IPython;
55 54
56 55 }(IPython));
@@ -1,87 +1,97 b''
1 1
2 2 //============================================================================
3 3 // LeftPanel
4 4 //============================================================================
5 5
6 6
7 7 var IPython = (function (IPython) {
8 8
9 9 var utils = IPython.utils;
10 10
11 11 var LeftPanel = function (left_panel_selector, left_panel_splitter_selector) {
12 12 this.left_panel_element = $(left_panel_selector);
13 13 this.left_panel_splitter_element = $(left_panel_splitter_selector);
14 14 this.expanded = true;
15 15 this.width = 250;
16 16 this.style();
17 17 this.bind_events();
18 this.create_children();
18 19 };
19 20
20 21
21 22 LeftPanel.prototype.style = function () {
22 23 this.left_panel_splitter_element.addClass('border-box-sizing ui-widget ui-state-default');
23 24 this.left_panel_element.addClass('border-box-sizing ui-widget');
24 25 this.left_panel_element.width(this.width);
25 26 this.left_panel_splitter_element.css({left : this.width});
26 27 };
27 28
28 29
29 30 LeftPanel.prototype.bind_events = function () {
30 31 var that = this;
31 32
32 33 this.left_panel_element.bind('collapse_left_panel', function () {
33 34 that.left_panel_element.hide('fast');
34 35 that.left_panel_splitter_element.animate({left : 0}, 'fast');
35 36 });
36 37
37 38 this.left_panel_element.bind('expand_left_panel', function () {
38 39 that.left_panel_element.show('fast');
39 40 that.left_panel_splitter_element.animate({left : that.width}, 'fast');
40 41 });
41 42
42 43 this.left_panel_splitter_element.hover(
43 44 function () {
44 45 that.left_panel_splitter_element.addClass('ui-state-hover');
45 46 },
46 47 function () {
47 48 that.left_panel_splitter_element.removeClass('ui-state-hover');
48 49 }
49 50 );
50 51
51 52 this.left_panel_splitter_element.click(function () {
52 53 that.toggle();
53 54 });
54 55
55 56 };
56 57
57 58
59 LeftPanel.prototype.create_children = function () {
60 this.notebook_section = new IPython.NotebookSection();
61 this.left_panel_element.append(this.notebook_section.element);
62 this.cell_section = new IPython.CellSection();
63 this.left_panel_element.append(this.cell_section.element);
64 this.kernel_section = new IPython.KernelSection();
65 this.left_panel_element.append(this.kernel_section.element);
66 }
67
58 68 LeftPanel.prototype.collapse = function () {
59 69 if (this.expanded === true) {
60 70 this.left_panel_element.add($('div#notebook')).trigger('collapse_left_panel');
61 71 this.expanded = false;
62 72 };
63 73 };
64 74
65 75
66 76 LeftPanel.prototype.expand = function () {
67 77 if (this.expanded !== true) {
68 78 this.left_panel_element.add($('div#notebook')).trigger('expand_left_panel');
69 79 this.expanded = true;
70 80 };
71 81 };
72 82
73 83
74 84 LeftPanel.prototype.toggle = function () {
75 85 if (this.expanded === true) {
76 86 this.collapse();
77 87 } else {
78 88 this.expand();
79 89 };
80 90 };
81 91
82 92 IPython.LeftPanel = LeftPanel;
83 93
84 94 return IPython;
85 95
86 96 }(IPython));
87 97
@@ -1,591 +1,590 b''
1 1
2 2 //============================================================================
3 3 // Notebook
4 4 //============================================================================
5 5
6 6 var IPython = (function (IPython) {
7 7
8 8 var utils = IPython.utils;
9 9
10 10 var Notebook = function (selector) {
11 11 this.element = $(selector);
12 12 this.element.scroll();
13 13 this.element.data("notebook", this);
14 14 this.next_prompt_number = 1;
15 15 this.kernel = null;
16 16 this.msg_cell_map = {};
17 17 this.filename = null;
18 18 this.notebook_load_re = /%notebook load/
19 19 this.notebook_save_re = /%notebook save/
20 20 this.notebook_filename_re = /(\w)+.ipynb/
21 21 this.style();
22 22 this.create_elements();
23 23 this.bind_events();
24 24 this.start_kernel();
25 25 };
26 26
27 27
28 28 Notebook.prototype.style = function () {
29 29 $('div#notebook').addClass('border-box-sizing');
30 30 };
31 31
32 32
33 33 Notebook.prototype.create_elements = function () {
34 34 // We add this end_space div to the end of the notebook div to:
35 35 // i) provide a margin between the last cell and the end of the notebook
36 36 // ii) to prevent the div from scrolling up when the last cell is being
37 37 // edited, but is too low on the page, which browsers will do automatically.
38 38 this.element.append($('<div class="end_space"></div>').height(50));
39 39 $('div#notebook').addClass('border-box-sizing');
40 40 };
41 41
42 42
43 43 Notebook.prototype.bind_events = function () {
44 44 var that = this;
45 45 $(document).keydown(function (event) {
46 46 // console.log(event);
47 47 if (event.which === 38) {
48 48 var cell = that.selected_cell();
49 49 if (cell.at_top()) {
50 50 event.preventDefault();
51 51 that.select_prev();
52 52 };
53 53 } else if (event.which === 40) {
54 54 var cell = that.selected_cell();
55 55 if (cell.at_bottom()) {
56 56 event.preventDefault();
57 57 that.select_next();
58 58 };
59 59 } else if (event.which === 13 && event.shiftKey) {
60 60 // The focus is not quite working here.
61 61 var cell = that.selected_cell();
62 62 var cell_index = that.find_cell_index(cell);
63 63 // TODO: the logic here needs to be moved into appropriate
64 64 // methods of Notebook.
65 65 if (cell instanceof IPython.CodeCell) {
66 66 event.preventDefault();
67 67 cell.clear_output();
68 68 var code = cell.get_code();
69 69 if (that.notebook_load_re.test(code)) {
70 70 var code_parts = code.split(' ');
71 71 if (code_parts.length === 3) {
72 72 that.load_notebook(code_parts[2]);
73 73 };
74 74 } else if (that.notebook_save_re.test(code)) {
75 75 var code_parts = code.split(' ');
76 76 if (code_parts.length === 3) {
77 77 that.save_notebook(code_parts[2]);
78 78 } else {
79 79 that.save_notebook()
80 80 };
81 81 } else {
82 82 var msg_id = that.kernel.execute(cell.get_code());
83 83 that.msg_cell_map[msg_id] = cell.cell_id;
84 84 };
85 85 } else if (cell instanceof IPython.TextCell) {
86 86 event.preventDefault();
87 87 cell.render();
88 88 }
89 89 if (cell_index === (that.ncells()-1)) {
90 90 that.insert_code_cell_after();
91 91 // If we are adding a new cell at the end, scroll down to show it.
92 92 that.scroll_to_bottom();
93 93 } else {
94 94 that.select(cell_index+1);
95 95 };
96 96 };
97 97 });
98 98
99 99 this.element.bind('collapse_pager', function () {
100 100 var app_height = $('div#notebook_app').height(); // content height
101 101 var splitter_height = $('div#pager_splitter').outerHeight(true);
102 102 var new_height = app_height - splitter_height;
103 103 that.element.animate({height : new_height + 'px'}, 'fast');
104 104 });
105 105
106 106 this.element.bind('expand_pager', function () {
107 107 var app_height = $('div#notebook_app').height(); // content height
108 108 var splitter_height = $('div#pager_splitter').outerHeight(true);
109 109 var pager_height = $('div#pager').outerHeight(true);
110 110 var new_height = app_height - pager_height - splitter_height;
111 111 that.element.animate({height : new_height + 'px'}, 'fast');
112 112 });
113 113
114 114 this.element.bind('collapse_left_panel', function () {
115 115 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
116 116 var new_margin = splitter_width;
117 117 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
118 118 });
119 119
120 120 this.element.bind('expand_left_panel', function () {
121 121 var splitter_width = $('div#left_panel_splitter').outerWidth(true);
122 122 var left_panel_width = IPython.left_panel.width;
123 123 var new_margin = splitter_width + left_panel_width;
124 console.log('expand', splitter_width, left_panel_width, new_margin);
125 124 $('div#notebook_panel').animate({marginLeft : new_margin + 'px'}, 'fast');
126 125 });
127 126 };
128 127
129 128
130 129 Notebook.prototype.scroll_to_bottom = function () {
131 130 this.element.animate({scrollTop:this.element.get(0).scrollHeight}, 'slow');
132 131 };
133 132
134 133 // Cell indexing, retrieval, etc.
135 134
136 135
137 136 Notebook.prototype.cell_elements = function () {
138 137 return this.element.children("div.cell");
139 138 }
140 139
141 140
142 141 Notebook.prototype.ncells = function (cell) {
143 142 return this.cell_elements().length;
144 143 }
145 144
146 145
147 146 // TODO: we are often calling cells as cells()[i], which we should optimize
148 147 // to cells(i) or a new method.
149 148 Notebook.prototype.cells = function () {
150 149 return this.cell_elements().toArray().map(function (e) {
151 150 return $(e).data("cell");
152 151 });
153 152 }
154 153
155 154
156 155 Notebook.prototype.find_cell_index = function (cell) {
157 156 var result = null;
158 157 this.cell_elements().filter(function (index) {
159 158 if ($(this).data("cell") === cell) {
160 159 result = index;
161 160 };
162 161 });
163 162 return result;
164 163 };
165 164
166 165
167 166 Notebook.prototype.index_or_selected = function (index) {
168 167 return index || this.selected_index() || 0;
169 168 }
170 169
171 170
172 171 Notebook.prototype.select = function (index) {
173 172 if (index !== undefined && index >= 0 && index < this.ncells()) {
174 173 if (this.selected_index() !== null) {
175 174 this.selected_cell().unselect();
176 175 };
177 176 this.cells()[index].select();
178 177 if (index === (this.ncells()-1)) {
179 178 this.scroll_to_bottom();
180 179 };
181 180 };
182 181 return this;
183 182 };
184 183
185 184
186 185 Notebook.prototype.select_next = function () {
187 186 var index = this.selected_index();
188 187 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
189 188 this.select(index+1);
190 189 };
191 190 return this;
192 191 };
193 192
194 193
195 194 Notebook.prototype.select_prev = function () {
196 195 var index = this.selected_index();
197 196 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
198 197 this.select(index-1);
199 198 };
200 199 return this;
201 200 };
202 201
203 202
204 203 Notebook.prototype.selected_index = function () {
205 204 var result = null;
206 205 this.cell_elements().filter(function (index) {
207 206 if ($(this).data("cell").selected === true) {
208 207 result = index;
209 208 };
210 209 });
211 210 return result;
212 211 };
213 212
214 213
215 214 Notebook.prototype.cell_for_msg = function (msg_id) {
216 215 var cell_id = this.msg_cell_map[msg_id];
217 216 var result = null;
218 217 this.cell_elements().filter(function (index) {
219 218 cell = $(this).data("cell");
220 219 if (cell.cell_id === cell_id) {
221 220 result = cell;
222 221 };
223 222 });
224 223 return result;
225 224 };
226 225
227 226
228 227 Notebook.prototype.selected_cell = function () {
229 228 return this.cell_elements().eq(this.selected_index()).data("cell");
230 229 }
231 230
232 231
233 232 // Cell insertion, deletion and moving.
234 233
235 234
236 235 Notebook.prototype.delete_cell = function (index) {
237 236 var i = index || this.selected_index();
238 237 if (i !== null && i >= 0 && i < this.ncells()) {
239 238 this.cell_elements().eq(i).remove();
240 239 if (i === (this.ncells())) {
241 240 this.select(i-1);
242 241 } else {
243 242 this.select(i);
244 243 };
245 244 };
246 245 return this;
247 246 };
248 247
249 248
250 249 Notebook.prototype.append_cell = function (cell) {
251 250 this.element.find('div.end_space').before(cell.element);
252 251 return this;
253 252 };
254 253
255 254
256 255 Notebook.prototype.insert_cell_after = function (cell, index) {
257 256 var ncells = this.ncells();
258 257 if (ncells === 0) {
259 258 this.append_cell(cell);
260 259 return this;
261 260 };
262 261 if (index >= 0 && index < ncells) {
263 262 this.cell_elements().eq(index).after(cell.element);
264 263 };
265 264 return this
266 265 };
267 266
268 267
269 268 Notebook.prototype.insert_cell_before = function (cell, index) {
270 269 var ncells = this.ncells();
271 270 if (ncells === 0) {
272 271 this.append_cell(cell);
273 272 return this;
274 273 };
275 274 if (index >= 0 && index < ncells) {
276 275 this.cell_elements().eq(index).before(cell.element);
277 276 };
278 277 return this;
279 278 };
280 279
281 280
282 281 Notebook.prototype.move_cell_up = function (index) {
283 282 var i = index || this.selected_index();
284 283 if (i !== null && i < this.ncells() && i > 0) {
285 284 var pivot = this.cell_elements().eq(i-1);
286 285 var tomove = this.cell_elements().eq(i);
287 286 if (pivot !== null && tomove !== null) {
288 287 tomove.detach();
289 288 pivot.before(tomove);
290 289 this.select(i-1);
291 290 };
292 291 };
293 292 return this;
294 293 }
295 294
296 295
297 296 Notebook.prototype.move_cell_down = function (index) {
298 297 var i = index || this.selected_index();
299 298 if (i !== null && i < (this.ncells()-1) && i >= 0) {
300 299 var pivot = this.cell_elements().eq(i+1)
301 300 var tomove = this.cell_elements().eq(i)
302 301 if (pivot !== null && tomove !== null) {
303 302 tomove.detach();
304 303 pivot.after(tomove);
305 304 this.select(i+1);
306 305 };
307 306 };
308 307 return this;
309 308 }
310 309
311 310
312 311 Notebook.prototype.sort_cells = function () {
313 312 var ncells = this.ncells();
314 313 var sindex = this.selected_index();
315 314 var swapped;
316 315 do {
317 316 swapped = false
318 317 for (var i=1; i<ncells; i++) {
319 318 current = this.cell_elements().eq(i).data("cell");
320 319 previous = this.cell_elements().eq(i-1).data("cell");
321 320 if (previous.input_prompt_number > current.input_prompt_number) {
322 321 this.move_cell_up(i);
323 322 swapped = true;
324 323 };
325 324 };
326 325 } while (swapped);
327 326 this.select(sindex);
328 327 return this;
329 328 };
330 329
331 330
332 331 Notebook.prototype.insert_code_cell_before = function (index) {
333 332 // TODO: Bounds check for i
334 333 var i = this.index_or_selected(index);
335 334 var cell = new IPython.CodeCell(this);
336 335 cell.set_input_prompt(this.next_prompt_number);
337 336 this.next_prompt_number = this.next_prompt_number + 1;
338 337 this.insert_cell_before(cell, i);
339 338 this.select(this.find_cell_index(cell));
340 339 return this;
341 340 }
342 341
343 342
344 343 Notebook.prototype.insert_code_cell_after = function (index) {
345 344 // TODO: Bounds check for i
346 345 var i = this.index_or_selected(index);
347 346 var cell = new IPython.CodeCell(this);
348 347 cell.set_input_prompt(this.next_prompt_number);
349 348 this.next_prompt_number = this.next_prompt_number + 1;
350 349 this.insert_cell_after(cell, i);
351 350 this.select(this.find_cell_index(cell));
352 351 return this;
353 352 }
354 353
355 354
356 355 Notebook.prototype.insert_text_cell_before = function (index) {
357 356 // TODO: Bounds check for i
358 357 var i = this.index_or_selected(index);
359 358 var cell = new IPython.TextCell(this);
360 359 cell.config_mathjax();
361 360 this.insert_cell_before(cell, i);
362 361 this.select(this.find_cell_index(cell));
363 362 return this;
364 363 }
365 364
366 365
367 366 Notebook.prototype.insert_text_cell_after = function (index) {
368 367 // TODO: Bounds check for i
369 368 var i = this.index_or_selected(index);
370 369 var cell = new IPython.TextCell(this);
371 370 cell.config_mathjax();
372 371 this.insert_cell_after(cell, i);
373 372 this.select(this.find_cell_index(cell));
374 373 return this;
375 374 }
376 375
377 376
378 377 Notebook.prototype.text_to_code = function (index) {
379 378 // TODO: Bounds check for i
380 379 var i = this.index_or_selected(index);
381 380 var source_element = this.cell_elements().eq(i);
382 381 var source_cell = source_element.data("cell");
383 382 if (source_cell instanceof IPython.TextCell) {
384 383 this.insert_code_cell_after(i);
385 384 var target_cell = this.cells()[i+1];
386 385 target_cell.set_code(source_cell.get_text());
387 386 source_element.remove();
388 387 };
389 388 };
390 389
391 390
392 391 Notebook.prototype.code_to_text = function (index) {
393 392 // TODO: Bounds check for i
394 393 var i = this.index_or_selected(index);
395 394 var source_element = this.cell_elements().eq(i);
396 395 var source_cell = source_element.data("cell");
397 396 if (source_cell instanceof IPython.CodeCell) {
398 397 this.insert_text_cell_after(i);
399 398 var target_cell = this.cells()[i+1];
400 399 var text = source_cell.get_code();
401 400 if (text === "") {text = target_cell.placeholder;};
402 401 target_cell.set_text(text);
403 402 source_element.remove();
404 403 target_cell.edit();
405 404 };
406 405 };
407 406
408 407
409 408 // Cell collapsing
410 409
411 410 Notebook.prototype.collapse = function (index) {
412 411 var i = this.index_or_selected(index);
413 412 this.cells()[i].collapse();
414 413 };
415 414
416 415
417 416 Notebook.prototype.expand = function (index) {
418 417 var i = this.index_or_selected(index);
419 418 this.cells()[i].expand();
420 419 };
421 420
422 421
423 422 // Kernel related things
424 423
425 424 Notebook.prototype.start_kernel = function () {
426 425 this.kernel = new IPython.Kernel();
427 426 this.kernel.start_kernel($.proxy(this.kernel_started, this));
428 427 };
429 428
430 429
431 430 Notebook.prototype.handle_shell_reply = function (e) {
432 431 reply = $.parseJSON(e.data);
433 432 var header = reply.header;
434 433 var content = reply.content;
435 434 var msg_type = header.msg_type;
436 console.log(reply);
435 // console.log(reply);
437 436 var cell = this.cell_for_msg(reply.parent_header.msg_id);
438 437 if (msg_type === "execute_reply") {
439 438 cell.set_input_prompt(content.execution_count);
440 439 };
441 440 var payload = content.payload || [];
442 441 this.handle_payload(content.payload);
443 442 };
444 443
445 444
446 445 Notebook.prototype.handle_payload = function (payload) {
447 446 var l = payload.length;
448 447 if (l > 0) {
449 448 IPython.pager.clear();
450 449 IPython.pager.expand();
451 450 };
452 451 for (var i=0; i<l; i++) {
453 452 IPython.pager.append_text(payload[i].text);
454 453 };
455 454 };
456 455
457 456
458 457 Notebook.prototype.handle_iopub_reply = function (e) {
459 458 reply = $.parseJSON(e.data);
460 459 var content = reply.content;
461 460 // console.log(reply);
462 461 var msg_type = reply.header.msg_type;
463 462 var cell = this.cell_for_msg(reply.parent_header.msg_id);
464 463 if (msg_type === "stream") {
465 464 cell.expand();
466 465 cell.append_stream(content.data + "\n");
467 466 } else if (msg_type === "display_data") {
468 467 cell.expand();
469 468 cell.append_display_data(content.data);
470 469 } else if (msg_type === "pyout") {
471 470 cell.expand();
472 471 cell.append_pyout(content.data, content.execution_count)
473 472 } else if (msg_type === "pyerr") {
474 473 cell.expand();
475 474 cell.append_pyerr(content.ename, content.evalue, content.traceback);
476 475 } else if (msg_type === "status") {
477 476 if (content.execution_state === "busy") {
478 477 this.kernel.status_busy();
479 478 } else if (content.execution_state === "idle") {
480 479 this.kernel.status_idle();
481 480 };
482 481 }
483 482 };
484 483
485 484
486 485 Notebook.prototype.kernel_started = function () {
487 486 console.log("Kernel started: ", this.kernel.kernel_id);
488 487 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
489 488 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
490 489 };
491 490
492 491
493 492 // Persistance and loading
494 493
495 494
496 495 Notebook.prototype.fromJSON = function (data) {
497 496 var ncells = this.ncells();
498 497 for (var i=0; i<ncells; i++) {
499 498 // Always delete cell 0 as they get renumbered as they are deleted.
500 499 this.delete_cell(0);
501 500 };
502 501 var new_cells = data.cells;
503 502 ncells = new_cells.length;
504 503 var cell_data = null;
505 504 for (var i=0; i<ncells; i++) {
506 505 cell_data = new_cells[i];
507 506 if (cell_data.cell_type == 'code') {
508 507 this.insert_code_cell_after();
509 508 this.selected_cell().fromJSON(cell_data);
510 509 } else if (cell_data.cell_type === 'text') {
511 510 this.insert_text_cell_after();
512 511 this.selected_cell().fromJSON(cell_data);
513 512 };
514 513 };
515 514 };
516 515
517 516
518 517 Notebook.prototype.toJSON = function () {
519 518 var cells = this.cells();
520 519 var ncells = cells.length;
521 520 cell_array = new Array(ncells);
522 521 for (var i=0; i<ncells; i++) {
523 522 cell_array[i] = cells[i].toJSON();
524 523 };
525 524 json = {
526 525 cells : cell_array
527 526 };
528 527 return json
529 528 };
530 529
531 530
532 531 Notebook.prototype.test_filename = function (filename) {
533 532 if (this.notebook_filename_re.test(filename)) {
534 533 return true;
535 534 } else {
536 535 var bad_filename = $('<div/>');
537 536 bad_filename.html(
538 537 "The filename you entered (" + filename + ") is not valid. Notebook filenames must have the following form: foo.ipynb"
539 538 );
540 539 bad_filename.dialog({title: 'Invalid filename', modal: true});
541 540 return false;
542 541 };
543 542 };
544 543
545 544 Notebook.prototype.save_notebook = function (filename) {
546 545 this.filename = filename || this.filename || '';
547 546 if (this.filename === '') {
548 547 var no_filename = $('<div/>');
549 548 no_filename.html(
550 549 "This notebook has no filename, please specify a filename of the form: foo.ipynb"
551 550 );
552 551 no_filename.dialog({title: 'Missing filename', modal: true});
553 552 return;
554 553 }
555 554 if (!this.test_filename(this.filename)) {return;}
556 555 var thedata = this.toJSON();
557 556 var settings = {
558 557 processData : false,
559 558 cache : false,
560 559 type : "PUT",
561 560 data : JSON.stringify(thedata),
562 561 success : function (data, status, xhr) {console.log(data);}
563 562 };
564 563 $.ajax("/notebooks/" + this.filename, settings);
565 564 };
566 565
567 566
568 567 Notebook.prototype.load_notebook = function (filename) {
569 568 if (!this.test_filename(filename)) {return;}
570 569 var that = this;
571 570 // We do the call with settings so we can set cache to false.
572 571 var settings = {
573 572 processData : false,
574 573 cache : false,
575 574 type : "GET",
576 575 dataType : "json",
577 576 success : function (data, status, xhr) {
578 577 that.fromJSON(data);
579 578 that.filename = filename;
580 579 that.kernel.restart();
581 580 }
582 581 };
583 582 $.ajax("/notebooks/" + filename, settings);
584 583 }
585 584
586 585 IPython.Notebook = Notebook;
587 586
588 587 return IPython;
589 588
590 589 }(IPython));
591 590
@@ -1,122 +1,123 b''
1 1 <!DOCTYPE HTML>
2 2 <html>
3 3
4 4 <head>
5 5 <meta charset="utf-8">
6 6
7 7 <title>IPython Notebook</title>
8 8
9 9 <link rel="stylesheet" href="static/jquery/css/themes/aristo/jquery-wijmo.css" type="text/css" />
10 10 <!-- <link rel="stylesheet" href="static/jquery/css/themes/rocket/jquery-wijmo.css" type="text/css" /> -->
11 11 <!-- <link rel="stylesheet" href="static/jquery/css/themes/smoothness/jquery-ui-1.8.14.custom.css" type="text/css" />-->
12 12
13 13 <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" charset="utf-8"></script>
14 14 <!-- <script type='text/javascript' src='static/mathjax/MathJax.js?config=TeX-AMS_HTML' charset='utf-8'></script> -->
15 15 <script type="text/javascript">
16 16 if (typeof MathJax == 'undefined') {
17 17 console.log("Trying to load local copy of MathJax");
18 18 document.write(unescape("%3Cscript type='text/javascript' src='static/mathjax/MathJax.js%3Fconfig=TeX-AMS_HTML' charset='utf-8'%3E%3C/script%3E"));
19 19 }
20 20 </script>
21 21
22 22 <link rel="stylesheet" href="static/codemirror2/lib/codemirror.css">
23 23 <link rel="stylesheet" href="static/codemirror2/mode/python/python.css">
24 24
25 25 <link rel="stylesheet" href="static/css/layout.css" type="text/css" />
26 26 <link rel="stylesheet" href="static/css/notebook.css" type="text/css" />
27 27
28 28 </head>
29 29
30 30 <body>
31 31
32 32 <div id="header">
33 33 <span id="ipython_notebook"><h1>IPython Notebook</h1></span>
34 34 </div>
35 35
36 36 <div id="notebook_app">
37 37
38 38 <div id="left_panel"></div>
39 39 <div id="left_panel_splitter"></div>
40 40 <div id="notebook_panel">
41 41 <div id="notebook"></div>
42 42 <div id="pager_splitter"></div>
43 43 <div id="pager"></div>
44 44 </div>
45 45
46 46 </div>
47 47
48 48 <script src="static/jquery/js/jquery-1.6.2.min.js" type="text/javascript" charset="utf-8"></script>
49 49 <script src="static/jquery/js/jquery-ui-1.8.14.custom.min.js" type="text/javascript" charset="utf-8"></script>
50 50 <script src="static/jquery/js/jquery.autogrow.js" type="text/javascript" charset="utf-8"></script>
51 51 <script src="static/js/namespace.js" type="text/javascript" charset="utf-8"></script>
52 52 <script src="static/js/utils.js" type="text/javascript" charset="utf-8"></script>
53 53 <script src="static/js/cell.js" type="text/javascript" charset="utf-8"></script>
54 54 <script src="static/js/codecell.js" type="text/javascript" charset="utf-8"></script>
55 55 <script src="static/js/textcell.js" type="text/javascript" charset="utf-8"></script>
56 56 <script src="static/js/kernel.js" type="text/javascript" charset="utf-8"></script>
57 57 <script src="static/js/layout.js" type="text/javascript" charset="utf-8"></script>
58 58 <script src="static/js/pager.js" type="text/javascript" charset="utf-8"></script>
59 <script src="static/js/panelsection.js" type="text/javascript" charset="utf-8"></script>
59 60 <script src="static/js/leftpanel.js" type="text/javascript" charset="utf-8"></script>
60 61 <script src="static/js/notebook.js" type="text/javascript" charset="utf-8"></script>
61 62 <script src="static/js/notebook_main.js" type="text/javascript" charset="utf-8"></script>
62 63 <script src="static/codemirror2/lib/codemirror.js"></script>
63 64 <script src="static/codemirror2/mode/python/python.js"></script>
64 65
65 66 </body>
66 67
67 68 </html>
68 69
69 70
70 71 <!--<div id="tools">-->
71 72
72 73 <!--<div id="menu_tabs">-->
73 74 <!-- <span id="kernel_status">Idle</span>-->
74 75 <!-- <ul>-->
75 76 <!-- <li><a href="#cell_tab">Cell</a></li>-->
76 77 <!-- <li><a href="#kernel_tab">Kernel</a></li>-->
77 78 <!-- <li><a href="#help_tab">Help</a></li>-->
78 79 <!-- </ul>-->
79 80 <!-- <div id="cell_tab">-->
80 81 <!-- <span id="cell_toolbar">-->
81 82 <!-- <span id="move_cell">-->
82 83 <!-- <button id="move_up">Move up</button>-->
83 84 <!-- <button id="move_down">Move down</button>-->
84 85 <!-- </span>-->
85 86 <!-- <span id="insert_delete">-->
86 87 <!-- <button id="insert_cell_before">Before</button>-->
87 88 <!-- <button id="insert_cell_after">After</button>-->
88 89 <!-- <button id="delete_cell">Delete</button>-->
89 90 <!-- </span>-->
90 91 <!-- <span id="cell_type">-->
91 92 <!-- <button id="to_code">Code</button>-->
92 93 <!-- <button id="to_text">Text</button>-->
93 94 <!-- </span>-->
94 95 <!-- <span id="sort">-->
95 96 <!-- <button id="sort_cells">Sort</button>-->
96 97 <!-- </span>-->
97 98 <!-- <span id="toggle">-->
98 99 <!-- <button id="collapse">Collapse</button>-->
99 100 <!-- <button id="expand">Expand</button>-->
100 101 <!-- </span>-->
101 102 <!-- </span>-->
102 103 <!-- </div>-->
103 104 <!-- <div id="kernel_tab">-->
104 105 <!-- <span id="kernel_toolbar">-->
105 106 <!-- <button id="interrupt_kernel">Interrupt</button>-->
106 107 <!-- <button id="restart_kernel">Restart</button>-->
107 108 <!-- </span>-->
108 109 <!-- </div>-->
109 110 <!-- <div id="help_tab">-->
110 111 <!-- <span id="help_toolbar">-->
111 112 <!-- <button><a href="http://docs.python.org" target="_blank">Python</a></button>-->
112 113 <!-- <button><a href="http://ipython.github.com/ipython-doc/dev/index.html" target="_blank">IPython</a></button>-->
113 114 <!-- <button><a href="http://matplotlib.sourceforge.net/" target="_blank">Matplotlib</a></button>-->
114 115 <!-- <button><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></button>-->
115 116 <!-- <button><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></button>-->
116 117 <!-- <button><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></button>-->
117 118 <!-- </span>-->
118 119 <!-- </div>-->
119 120 <!--</div>-->
120 121
121 122 <!--</div>-->
122 123
General Comments 0
You need to be logged in to leave comments. Login now