##// END OF EJS Templates
Using $.proxy to clean up callbacks.
Brian E. Granger -
Show More
@@ -1,115 +1,115 b''
1
1
2 //============================================================================
2 //============================================================================
3 // Kernel
3 // Kernel
4 //============================================================================
4 //============================================================================
5
5
6 var IPython = (function (IPython) {
6 var IPython = (function (IPython) {
7
7
8 var utils = IPython.utils;
8 var utils = IPython.utils;
9
9
10 var Kernel = function () {
10 var Kernel = function () {
11 this.kernel_id = null;
11 this.kernel_id = null;
12 this.base_url = "/kernels";
12 this.base_url = "/kernels";
13 this.kernel_url = null;
13 this.kernel_url = null;
14 };
14 };
15
15
16
16
17 Kernel.prototype.get_msg = function (msg_type, content) {
17 Kernel.prototype.get_msg = function (msg_type, content) {
18 var msg = {
18 var msg = {
19 header : {
19 header : {
20 msg_id : utils.uuid(),
20 msg_id : utils.uuid(),
21 username : "bgranger",
21 username : "bgranger",
22 session: this.session_id,
22 session: this.session_id,
23 msg_type : msg_type
23 msg_type : msg_type
24 },
24 },
25 content : content,
25 content : content,
26 parent_header : {}
26 parent_header : {}
27 };
27 };
28 return msg;
28 return msg;
29 }
29 }
30
30
31 Kernel.prototype.start_kernel = function (callback, context) {
31 Kernel.prototype.start_kernel = function (callback) {
32 var that = this;
32 var that = this;
33 $.post(this.base_url,
33 $.post(this.base_url,
34 function (kernel_id) {
34 function (kernel_id) {
35 that._handle_start_kernel(kernel_id, callback, context);
35 that._handle_start_kernel(kernel_id, callback);
36 },
36 },
37 'json'
37 'json'
38 );
38 );
39 };
39 };
40
40
41
41
42 Kernel.prototype._handle_start_kernel = function (kernel_id, callback, context) {
42 Kernel.prototype._handle_start_kernel = function (kernel_id, callback) {
43 this.kernel_id = kernel_id;
43 this.kernel_id = kernel_id;
44 this.kernel_url = this.base_url + "/" + this.kernel_id;
44 this.kernel_url = this.base_url + "/" + this.kernel_id;
45 this._start_channels();
45 this._start_channels();
46 callback.call(context);
46 callback();
47 };
47 };
48
48
49
49
50 Kernel.prototype._start_channels = function () {
50 Kernel.prototype._start_channels = function () {
51 var ws_url = "ws://127.0.0.1:8888" + this.kernel_url;
51 var ws_url = "ws://127.0.0.1:8888" + this.kernel_url;
52 this.shell_channel = new WebSocket(ws_url + "/shell");
52 this.shell_channel = new WebSocket(ws_url + "/shell");
53 this.iopub_channel = new WebSocket(ws_url + "/iopub");
53 this.iopub_channel = new WebSocket(ws_url + "/iopub");
54 }
54 }
55
55
56
56
57 Kernel.prototype.execute = function (code) {
57 Kernel.prototype.execute = function (code) {
58 var content = {
58 var content = {
59 code : code,
59 code : code,
60 silent : false,
60 silent : false,
61 user_variables : [],
61 user_variables : [],
62 user_expressions : {}
62 user_expressions : {}
63 };
63 };
64 var msg = this.get_msg("execute_request", content);
64 var msg = this.get_msg("execute_request", content);
65 this.shell_channel.send(JSON.stringify(msg));
65 this.shell_channel.send(JSON.stringify(msg));
66 return msg.header.msg_id;
66 return msg.header.msg_id;
67 }
67 }
68
68
69
69
70 Kernel.prototype.interrupt = function () {
70 Kernel.prototype.interrupt = function () {
71 $.post(this.kernel_url + "/interrupt");
71 $.post(this.kernel_url + "/interrupt");
72 };
72 };
73
73
74
74
75 Kernel.prototype.restart = function () {
75 Kernel.prototype.restart = function () {
76 this.status_restarting();
76 this.status_restarting();
77 url = this.kernel_url + "/restart"
77 url = this.kernel_url + "/restart"
78 var that = this;
78 var that = this;
79 $.post(url, function (kernel_id) {
79 $.post(url, function (kernel_id) {
80 console.log("Kernel restarted: " + kernel_id);
80 console.log("Kernel restarted: " + kernel_id);
81 that.kernel_id = kernel_id;
81 that.kernel_id = kernel_id;
82 that.kernel_url = that.base_url + "/" + that.kernel_id;
82 that.kernel_url = that.base_url + "/" + that.kernel_id;
83 that.status_idle();
83 that.status_idle();
84 }, 'json');
84 }, 'json');
85 };
85 };
86
86
87
87
88 Kernel.prototype.status_busy = function () {
88 Kernel.prototype.status_busy = function () {
89 $("#kernel_status").removeClass("status_idle");
89 $("#kernel_status").removeClass("status_idle");
90 $("#kernel_status").removeClass("status_restarting");
90 $("#kernel_status").removeClass("status_restarting");
91 $("#kernel_status").addClass("status_busy");
91 $("#kernel_status").addClass("status_busy");
92 $("#kernel_status").text("Busy");
92 $("#kernel_status").text("Busy");
93 };
93 };
94
94
95
95
96 Kernel.prototype.status_idle = function () {
96 Kernel.prototype.status_idle = function () {
97 $("#kernel_status").removeClass("status_busy");
97 $("#kernel_status").removeClass("status_busy");
98 $("#kernel_status").removeClass("status_restarting");
98 $("#kernel_status").removeClass("status_restarting");
99 $("#kernel_status").addClass("status_idle");
99 $("#kernel_status").addClass("status_idle");
100 $("#kernel_status").text("Idle");
100 $("#kernel_status").text("Idle");
101 };
101 };
102
102
103 Kernel.prototype.status_restarting = function () {
103 Kernel.prototype.status_restarting = function () {
104 $("#kernel_status").removeClass("status_busy");
104 $("#kernel_status").removeClass("status_busy");
105 $("#kernel_status").removeClass("status_idle");
105 $("#kernel_status").removeClass("status_idle");
106 $("#kernel_status").addClass("status_restarting");
106 $("#kernel_status").addClass("status_restarting");
107 $("#kernel_status").text("Restarting");
107 $("#kernel_status").text("Restarting");
108 };
108 };
109
109
110 IPython.Kernel = Kernel;
110 IPython.Kernel = Kernel;
111
111
112 return IPython;
112 return IPython;
113
113
114 }(IPython));
114 }(IPython));
115
115
@@ -1,515 +1,518 b''
1
1
2 //============================================================================
2 //============================================================================
3 // Notebook
3 // Notebook
4 //============================================================================
4 //============================================================================
5
5
6 var IPython = (function (IPython) {
6 var IPython = (function (IPython) {
7
7
8 var Notebook = function (selector) {
8 var Notebook = function (selector) {
9 this.element = $(selector);
9 this.element = $(selector);
10 this.element.scroll();
10 this.element.scroll();
11 this.element.data("notebook", this);
11 this.element.data("notebook", this);
12 this.next_prompt_number = 1;
12 this.next_prompt_number = 1;
13 this.kernel = null;
13 this.kernel = null;
14 this.msg_cell_map = {};
14 this.msg_cell_map = {};
15 this.filename = null;
15 this.filename = null;
16 this.notebook_load_re = /%notebook load/
16 this.notebook_load_re = /%notebook load/
17 this.notebook_save_re = /%notebook save/
17 this.notebook_save_re = /%notebook save/
18 this.notebook_filename_re = /(\w)+.ipynb/
18 this.notebook_filename_re = /(\w)+.ipynb/
19 this.bind_events();
19 this.bind_events();
20 this.start_kernel();
20 this.start_kernel();
21 };
21 };
22
22
23
23
24 Notebook.prototype.bind_events = function () {
24 Notebook.prototype.bind_events = function () {
25 var that = this;
25 var that = this;
26 $(document).keydown(function (event) {
26 $(document).keydown(function (event) {
27 // console.log(event);
27 // console.log(event);
28 if (event.which === 38) {
28 if (event.which === 38) {
29 var cell = that.selected_cell();
29 var cell = that.selected_cell();
30 if (cell.at_top()) {
30 if (cell.at_top()) {
31 event.preventDefault();
31 event.preventDefault();
32 that.select_prev();
32 that.select_prev();
33 };
33 };
34 } else if (event.which === 40) {
34 } else if (event.which === 40) {
35 var cell = that.selected_cell();
35 var cell = that.selected_cell();
36 if (cell.at_bottom()) {
36 if (cell.at_bottom()) {
37 event.preventDefault();
37 event.preventDefault();
38 that.select_next();
38 that.select_next();
39 };
39 };
40 } else if (event.which === 13 && event.shiftKey) {
40 } else if (event.which === 13 && event.shiftKey) {
41 // The focus is not quite working here.
41 // The focus is not quite working here.
42 var cell = that.selected_cell();
42 var cell = that.selected_cell();
43 var cell_index = that.find_cell_index(cell);
43 var cell_index = that.find_cell_index(cell);
44 // TODO: the logic here needs to be moved into appropriate
44 // TODO: the logic here needs to be moved into appropriate
45 // methods of Notebook.
45 // methods of Notebook.
46 if (cell instanceof IPython.CodeCell) {
46 if (cell instanceof IPython.CodeCell) {
47 event.preventDefault();
47 event.preventDefault();
48 cell.clear_output();
48 cell.clear_output();
49 var code = cell.get_code();
49 var code = cell.get_code();
50 if (that.notebook_load_re.test(code)) {
50 if (that.notebook_load_re.test(code)) {
51 var code_parts = code.split(' ');
51 var code_parts = code.split(' ');
52 if (code_parts.length === 3) {
52 if (code_parts.length === 3) {
53 that.load_notebook(code_parts[2]);
53 that.load_notebook(code_parts[2]);
54 };
54 };
55 } else if (that.notebook_save_re.test(code)) {
55 } else if (that.notebook_save_re.test(code)) {
56 var code_parts = code.split(' ');
56 var code_parts = code.split(' ');
57 if (code_parts.length === 3) {
57 if (code_parts.length === 3) {
58 that.save_notebook(code_parts[2]);
58 that.save_notebook(code_parts[2]);
59 } else {
59 } else {
60 that.save_notebook()
60 that.save_notebook()
61 };
61 };
62 } else {
62 } else {
63 var msg_id = that.kernel.execute(cell.get_code());
63 var msg_id = that.kernel.execute(cell.get_code());
64 that.msg_cell_map[msg_id] = cell.cell_id;
64 that.msg_cell_map[msg_id] = cell.cell_id;
65 };
65 };
66 } else if (cell instanceof IPython.TextCell) {
66 } else if (cell instanceof IPython.TextCell) {
67 event.preventDefault();
67 event.preventDefault();
68 cell.render();
68 cell.render();
69 }
69 }
70 if (cell_index === (that.ncells()-1)) {
70 if (cell_index === (that.ncells()-1)) {
71 that.insert_code_cell_after();
71 that.insert_code_cell_after();
72 } else {
72 } else {
73 that.select(cell_index+1);
73 that.select(cell_index+1);
74 };
74 };
75 };
75 };
76 });
76 });
77 };
77 };
78
78
79
79
80 // Cell indexing, retrieval, etc.
80 // Cell indexing, retrieval, etc.
81
81
82
82
83 Notebook.prototype.cell_elements = function () {
83 Notebook.prototype.cell_elements = function () {
84 return this.element.children("div.cell");
84 return this.element.children("div.cell");
85 }
85 }
86
86
87
87
88 Notebook.prototype.ncells = function (cell) {
88 Notebook.prototype.ncells = function (cell) {
89 return this.cell_elements().length;
89 return this.cell_elements().length;
90 }
90 }
91
91
92
92
93 // TODO: we are often calling cells as cells()[i], which we should optimize
93 // TODO: we are often calling cells as cells()[i], which we should optimize
94 // to cells(i) or a new method.
94 // to cells(i) or a new method.
95 Notebook.prototype.cells = function () {
95 Notebook.prototype.cells = function () {
96 return this.cell_elements().toArray().map(function (e) {
96 return this.cell_elements().toArray().map(function (e) {
97 return $(e).data("cell");
97 return $(e).data("cell");
98 });
98 });
99 }
99 }
100
100
101
101
102 Notebook.prototype.find_cell_index = function (cell) {
102 Notebook.prototype.find_cell_index = function (cell) {
103 var result = null;
103 var result = null;
104 this.cell_elements().filter(function (index) {
104 this.cell_elements().filter(function (index) {
105 if ($(this).data("cell") === cell) {
105 if ($(this).data("cell") === cell) {
106 result = index;
106 result = index;
107 };
107 };
108 });
108 });
109 return result;
109 return result;
110 };
110 };
111
111
112
112
113 Notebook.prototype.index_or_selected = function (index) {
113 Notebook.prototype.index_or_selected = function (index) {
114 return index || this.selected_index() || 0;
114 return index || this.selected_index() || 0;
115 }
115 }
116
116
117
117
118 Notebook.prototype.select = function (index) {
118 Notebook.prototype.select = function (index) {
119 if (index !== undefined && index >= 0 && index < this.ncells()) {
119 if (index !== undefined && index >= 0 && index < this.ncells()) {
120 if (this.selected_index() !== null) {
120 if (this.selected_index() !== null) {
121 this.selected_cell().unselect();
121 this.selected_cell().unselect();
122 };
122 };
123 this.cells()[index].select();
123 this.cells()[index].select();
124 };
124 };
125 return this;
125 return this;
126 };
126 };
127
127
128
128
129 Notebook.prototype.select_next = function () {
129 Notebook.prototype.select_next = function () {
130 var index = this.selected_index();
130 var index = this.selected_index();
131 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
131 if (index !== null && index >= 0 && (index+1) < this.ncells()) {
132 this.select(index+1);
132 this.select(index+1);
133 };
133 };
134 return this;
134 return this;
135 };
135 };
136
136
137
137
138 Notebook.prototype.select_prev = function () {
138 Notebook.prototype.select_prev = function () {
139 var index = this.selected_index();
139 var index = this.selected_index();
140 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
140 if (index !== null && index >= 0 && (index-1) < this.ncells()) {
141 this.select(index-1);
141 this.select(index-1);
142 };
142 };
143 return this;
143 return this;
144 };
144 };
145
145
146
146
147 Notebook.prototype.selected_index = function () {
147 Notebook.prototype.selected_index = function () {
148 var result = null;
148 var result = null;
149 this.cell_elements().filter(function (index) {
149 this.cell_elements().filter(function (index) {
150 if ($(this).data("cell").selected === true) {
150 if ($(this).data("cell").selected === true) {
151 result = index;
151 result = index;
152 };
152 };
153 });
153 });
154 return result;
154 return result;
155 };
155 };
156
156
157
157
158 Notebook.prototype.cell_for_msg = function (msg_id) {
158 Notebook.prototype.cell_for_msg = function (msg_id) {
159 var cell_id = this.msg_cell_map[msg_id];
159 var cell_id = this.msg_cell_map[msg_id];
160 var result = null;
160 var result = null;
161 this.cell_elements().filter(function (index) {
161 this.cell_elements().filter(function (index) {
162 cell = $(this).data("cell");
162 cell = $(this).data("cell");
163 if (cell.cell_id === cell_id) {
163 if (cell.cell_id === cell_id) {
164 result = cell;
164 result = cell;
165 };
165 };
166 });
166 });
167 return result;
167 return result;
168 };
168 };
169
169
170
170
171 Notebook.prototype.selected_cell = function () {
171 Notebook.prototype.selected_cell = function () {
172 return this.cell_elements().eq(this.selected_index()).data("cell");
172 return this.cell_elements().eq(this.selected_index()).data("cell");
173 }
173 }
174
174
175
175
176 // Cell insertion, deletion and moving.
176 // Cell insertion, deletion and moving.
177
177
178
178
179 Notebook.prototype.delete_cell = function (index) {
179 Notebook.prototype.delete_cell = function (index) {
180 var i = index || this.selected_index();
180 var i = index || this.selected_index();
181 if (i !== null && i >= 0 && i < this.ncells()) {
181 if (i !== null && i >= 0 && i < this.ncells()) {
182 this.cell_elements().eq(i).remove();
182 this.cell_elements().eq(i).remove();
183 if (i === (this.ncells())) {
183 if (i === (this.ncells())) {
184 this.select(i-1);
184 this.select(i-1);
185 } else {
185 } else {
186 this.select(i);
186 this.select(i);
187 };
187 };
188 };
188 };
189 return this;
189 return this;
190 };
190 };
191
191
192
192
193 Notebook.prototype.append_cell = function (cell) {
193 Notebook.prototype.append_cell = function (cell) {
194 this.element.append(cell.element);
194 this.element.append(cell.element);
195 return this;
195 return this;
196 };
196 };
197
197
198
198
199 Notebook.prototype.insert_cell_after = function (cell, index) {
199 Notebook.prototype.insert_cell_after = function (cell, index) {
200 var ncells = this.ncells();
200 var ncells = this.ncells();
201 if (ncells === 0) {
201 if (ncells === 0) {
202 this.append_cell(cell);
202 this.append_cell(cell);
203 return this;
203 return this;
204 };
204 };
205 if (index >= 0 && index < ncells) {
205 if (index >= 0 && index < ncells) {
206 this.cell_elements().eq(index).after(cell.element);
206 this.cell_elements().eq(index).after(cell.element);
207 };
207 };
208 return this
208 return this
209 };
209 };
210
210
211
211
212 Notebook.prototype.insert_cell_before = function (cell, index) {
212 Notebook.prototype.insert_cell_before = function (cell, index) {
213 var ncells = this.ncells();
213 var ncells = this.ncells();
214 if (ncells === 0) {
214 if (ncells === 0) {
215 this.append_cell(cell);
215 this.append_cell(cell);
216 return this;
216 return this;
217 };
217 };
218 if (index >= 0 && index < ncells) {
218 if (index >= 0 && index < ncells) {
219 this.cell_elements().eq(index).before(cell.element);
219 this.cell_elements().eq(index).before(cell.element);
220 };
220 };
221 return this;
221 return this;
222 };
222 };
223
223
224
224
225 Notebook.prototype.move_cell_up = function (index) {
225 Notebook.prototype.move_cell_up = function (index) {
226 var i = index || this.selected_index();
226 var i = index || this.selected_index();
227 if (i !== null && i < this.ncells() && i > 0) {
227 if (i !== null && i < this.ncells() && i > 0) {
228 var pivot = this.cell_elements().eq(i-1);
228 var pivot = this.cell_elements().eq(i-1);
229 var tomove = this.cell_elements().eq(i);
229 var tomove = this.cell_elements().eq(i);
230 if (pivot !== null && tomove !== null) {
230 if (pivot !== null && tomove !== null) {
231 tomove.detach();
231 tomove.detach();
232 pivot.before(tomove);
232 pivot.before(tomove);
233 this.select(i-1);
233 this.select(i-1);
234 };
234 };
235 };
235 };
236 return this;
236 return this;
237 }
237 }
238
238
239
239
240 Notebook.prototype.move_cell_down = function (index) {
240 Notebook.prototype.move_cell_down = function (index) {
241 var i = index || this.selected_index();
241 var i = index || this.selected_index();
242 if (i !== null && i < (this.ncells()-1) && i >= 0) {
242 if (i !== null && i < (this.ncells()-1) && i >= 0) {
243 var pivot = this.cell_elements().eq(i+1)
243 var pivot = this.cell_elements().eq(i+1)
244 var tomove = this.cell_elements().eq(i)
244 var tomove = this.cell_elements().eq(i)
245 if (pivot !== null && tomove !== null) {
245 if (pivot !== null && tomove !== null) {
246 tomove.detach();
246 tomove.detach();
247 pivot.after(tomove);
247 pivot.after(tomove);
248 this.select(i+1);
248 this.select(i+1);
249 };
249 };
250 };
250 };
251 return this;
251 return this;
252 }
252 }
253
253
254
254
255 Notebook.prototype.sort_cells = function () {
255 Notebook.prototype.sort_cells = function () {
256 var ncells = this.ncells();
256 var ncells = this.ncells();
257 var sindex = this.selected_index();
257 var sindex = this.selected_index();
258 var swapped;
258 var swapped;
259 do {
259 do {
260 swapped = false
260 swapped = false
261 for (var i=1; i<ncells; i++) {
261 for (var i=1; i<ncells; i++) {
262 current = this.cell_elements().eq(i).data("cell");
262 current = this.cell_elements().eq(i).data("cell");
263 previous = this.cell_elements().eq(i-1).data("cell");
263 previous = this.cell_elements().eq(i-1).data("cell");
264 if (previous.input_prompt_number > current.input_prompt_number) {
264 if (previous.input_prompt_number > current.input_prompt_number) {
265 this.move_cell_up(i);
265 this.move_cell_up(i);
266 swapped = true;
266 swapped = true;
267 };
267 };
268 };
268 };
269 } while (swapped);
269 } while (swapped);
270 this.select(sindex);
270 this.select(sindex);
271 return this;
271 return this;
272 };
272 };
273
273
274
274
275 Notebook.prototype.insert_code_cell_before = function (index) {
275 Notebook.prototype.insert_code_cell_before = function (index) {
276 // TODO: Bounds check for i
276 // TODO: Bounds check for i
277 var i = this.index_or_selected(index);
277 var i = this.index_or_selected(index);
278 var cell = new IPython.CodeCell(this);
278 var cell = new IPython.CodeCell(this);
279 cell.set_input_prompt(this.next_prompt_number);
279 cell.set_input_prompt(this.next_prompt_number);
280 this.next_prompt_number = this.next_prompt_number + 1;
280 this.next_prompt_number = this.next_prompt_number + 1;
281 this.insert_cell_before(cell, i);
281 this.insert_cell_before(cell, i);
282 this.select(this.find_cell_index(cell));
282 this.select(this.find_cell_index(cell));
283 return this;
283 return this;
284 }
284 }
285
285
286
286
287 Notebook.prototype.insert_code_cell_after = function (index) {
287 Notebook.prototype.insert_code_cell_after = function (index) {
288 // TODO: Bounds check for i
288 // TODO: Bounds check for i
289 var i = this.index_or_selected(index);
289 var i = this.index_or_selected(index);
290 var cell = new IPython.CodeCell(this);
290 var cell = new IPython.CodeCell(this);
291 cell.set_input_prompt(this.next_prompt_number);
291 cell.set_input_prompt(this.next_prompt_number);
292 this.next_prompt_number = this.next_prompt_number + 1;
292 this.next_prompt_number = this.next_prompt_number + 1;
293 this.insert_cell_after(cell, i);
293 this.insert_cell_after(cell, i);
294 this.select(this.find_cell_index(cell));
294 this.select(this.find_cell_index(cell));
295 return this;
295 return this;
296 }
296 }
297
297
298
298
299 Notebook.prototype.insert_text_cell_before = function (index) {
299 Notebook.prototype.insert_text_cell_before = function (index) {
300 // TODO: Bounds check for i
300 // TODO: Bounds check for i
301 var i = this.index_or_selected(index);
301 var i = this.index_or_selected(index);
302 var cell = new IPython.TextCell(this);
302 var cell = new IPython.TextCell(this);
303 cell.config_mathjax();
303 cell.config_mathjax();
304 this.insert_cell_before(cell, i);
304 this.insert_cell_before(cell, i);
305 this.select(this.find_cell_index(cell));
305 this.select(this.find_cell_index(cell));
306 return this;
306 return this;
307 }
307 }
308
308
309
309
310 Notebook.prototype.insert_text_cell_after = function (index) {
310 Notebook.prototype.insert_text_cell_after = function (index) {
311 // TODO: Bounds check for i
311 // TODO: Bounds check for i
312 var i = this.index_or_selected(index);
312 var i = this.index_or_selected(index);
313 var cell = new IPython.TextCell(this);
313 var cell = new IPython.TextCell(this);
314 cell.config_mathjax();
314 cell.config_mathjax();
315 this.insert_cell_after(cell, i);
315 this.insert_cell_after(cell, i);
316 this.select(this.find_cell_index(cell));
316 this.select(this.find_cell_index(cell));
317 return this;
317 return this;
318 }
318 }
319
319
320
320
321 Notebook.prototype.text_to_code = function (index) {
321 Notebook.prototype.text_to_code = function (index) {
322 // TODO: Bounds check for i
322 // TODO: Bounds check for i
323 var i = this.index_or_selected(index);
323 var i = this.index_or_selected(index);
324 var source_element = this.cell_elements().eq(i);
324 var source_element = this.cell_elements().eq(i);
325 var source_cell = source_element.data("cell");
325 var source_cell = source_element.data("cell");
326 if (source_cell instanceof IPython.TextCell) {
326 if (source_cell instanceof IPython.TextCell) {
327 this.insert_code_cell_after(i);
327 this.insert_code_cell_after(i);
328 var target_cell = this.cells()[i+1];
328 var target_cell = this.cells()[i+1];
329 target_cell.set_code(source_cell.get_text());
329 target_cell.set_code(source_cell.get_text());
330 source_element.remove();
330 source_element.remove();
331 };
331 };
332 };
332 };
333
333
334
334
335 Notebook.prototype.code_to_text = function (index) {
335 Notebook.prototype.code_to_text = function (index) {
336 // TODO: Bounds check for i
336 // TODO: Bounds check for i
337 var i = this.index_or_selected(index);
337 var i = this.index_or_selected(index);
338 var source_element = this.cell_elements().eq(i);
338 var source_element = this.cell_elements().eq(i);
339 var source_cell = source_element.data("cell");
339 var source_cell = source_element.data("cell");
340 if (source_cell instanceof IPython.CodeCell) {
340 if (source_cell instanceof IPython.CodeCell) {
341 this.insert_text_cell_after(i);
341 this.insert_text_cell_after(i);
342 var target_cell = this.cells()[i+1];
342 var target_cell = this.cells()[i+1];
343 var text = source_cell.get_code();
343 var text = source_cell.get_code();
344 if (text === "") {text = target_cell.placeholder;};
344 if (text === "") {text = target_cell.placeholder;};
345 target_cell.set_text(text);
345 target_cell.set_text(text);
346 source_element.remove();
346 source_element.remove();
347 target_cell.edit();
347 target_cell.edit();
348 };
348 };
349 };
349 };
350
350
351
351
352 // Cell collapsing
352 // Cell collapsing
353
353
354 Notebook.prototype.collapse = function (index) {
354 Notebook.prototype.collapse = function (index) {
355 var i = this.index_or_selected(index);
355 var i = this.index_or_selected(index);
356 this.cells()[i].collapse();
356 this.cells()[i].collapse();
357 };
357 };
358
358
359
359
360 Notebook.prototype.expand = function (index) {
360 Notebook.prototype.expand = function (index) {
361 var i = this.index_or_selected(index);
361 var i = this.index_or_selected(index);
362 this.cells()[i].expand();
362 this.cells()[i].expand();
363 };
363 };
364
364
365
365
366 // Kernel related things
366 // Kernel related things
367
367
368 Notebook.prototype.start_kernel = function () {
368 Notebook.prototype.start_kernel = function () {
369 this.kernel = new IPython.Kernel();
369 this.kernel = new IPython.Kernel();
370 this.kernel.start_kernel(this._kernel_started, this);
370 this.kernel.start_kernel($.proxy(this.kernel_started, this));
371 };
371 };
372
372
373
373
374 Notebook.prototype._kernel_started = function () {
374 Notebook.prototype.handle_shell_reply = function (e) {
375 console.log("Kernel started: ", this.kernel.kernel_id);
375 reply = $.parseJSON(e.data);
376 var that = this;
376 // console.log(reply);
377 var msg_type = reply.header.msg_type;
378 var cell = this.cell_for_msg(reply.parent_header.msg_id);
379 if (msg_type === "execute_reply") {
380 cell.set_input_prompt(reply.content.execution_count);
381 };
382 };
383
377
384
378 this.kernel.shell_channel.onmessage = function (e) {
385 Notebook.prototype.handle_iopub_reply = function (e) {
379 reply = $.parseJSON(e.data);
386 reply = $.parseJSON(e.data);
380 // console.log(reply);
387 var content = reply.content;
381 var msg_type = reply.header.msg_type;
388 // console.log(reply);
382 var cell = that.cell_for_msg(reply.parent_header.msg_id);
389 var msg_type = reply.header.msg_type;
383 if (msg_type === "execute_reply") {
390 var cell = this.cell_for_msg(reply.parent_header.msg_id);
384 cell.set_input_prompt(reply.content.execution_count);
391 if (msg_type === "stream") {
392 cell.expand();
393 cell.append_stream(content.data + "\n");
394 } else if (msg_type === "display_data") {
395 cell.expand();
396 cell.append_display_data(content.data);
397 } else if (msg_type === "pyout") {
398 cell.expand();
399 cell.append_pyout(content.data, content.execution_count)
400 } else if (msg_type === "pyerr") {
401 cell.expand();
402 cell.append_pyerr(content.ename, content.evalue, content.traceback);
403 } else if (msg_type === "status") {
404 if (content.execution_state === "busy") {
405 this.kernel.status_busy();
406 } else if (content.execution_state === "idle") {
407 this.kernel.status_idle();
385 };
408 };
386 };
409 }
410 };
387
411
388 this.kernel.iopub_channel.onmessage = function (e) {
412
389 reply = $.parseJSON(e.data);
413 Notebook.prototype.kernel_started = function () {
390 var content = reply.content;
414 console.log("Kernel started: ", this.kernel.kernel_id);
391 // console.log(reply);
415 this.kernel.shell_channel.onmessage = $.proxy(this.handle_shell_reply,this);
392 var msg_type = reply.header.msg_type;
416 this.kernel.iopub_channel.onmessage = $.proxy(this.handle_iopub_reply,this);
393 var cell = that.cell_for_msg(reply.parent_header.msg_id);
394 if (msg_type === "stream") {
395 cell.expand();
396 cell.append_stream(content.data + "\n");
397 } else if (msg_type === "display_data") {
398 cell.expand();
399 cell.append_display_data(content.data);
400 } else if (msg_type === "pyout") {
401 cell.expand();
402 cell.append_pyout(content.data, content.execution_count)
403 } else if (msg_type === "pyerr") {
404 cell.expand();
405 cell.append_pyerr(content.ename, content.evalue, content.traceback);
406 } else if (msg_type === "status") {
407 if (content.execution_state === "busy") {
408 that.kernel.status_busy();
409 } else if (content.execution_state === "idle") {
410 that.kernel.status_idle();
411 };
412 }
413 };
414 };
417 };
415
418
416
419
417 // Persistance and loading
420 // Persistance and loading
418
421
419
422
420 Notebook.prototype.fromJSON = function (data) {
423 Notebook.prototype.fromJSON = function (data) {
421 var ncells = this.ncells();
424 var ncells = this.ncells();
422 for (var i=0; i<ncells; i++) {
425 for (var i=0; i<ncells; i++) {
423 // Always delete cell 0 as they get renumbered as they are deleted.
426 // Always delete cell 0 as they get renumbered as they are deleted.
424 this.delete_cell(0);
427 this.delete_cell(0);
425 };
428 };
426 var new_cells = data.cells;
429 var new_cells = data.cells;
427 ncells = new_cells.length;
430 ncells = new_cells.length;
428 var cell_data = null;
431 var cell_data = null;
429 for (var i=0; i<ncells; i++) {
432 for (var i=0; i<ncells; i++) {
430 cell_data = new_cells[i];
433 cell_data = new_cells[i];
431 if (cell_data.cell_type == 'code') {
434 if (cell_data.cell_type == 'code') {
432 this.insert_code_cell_after();
435 this.insert_code_cell_after();
433 this.selected_cell().fromJSON(cell_data);
436 this.selected_cell().fromJSON(cell_data);
434 } else if (cell_data.cell_type === 'text') {
437 } else if (cell_data.cell_type === 'text') {
435 this.insert_text_cell_after();
438 this.insert_text_cell_after();
436 this.selected_cell().fromJSON(cell_data);
439 this.selected_cell().fromJSON(cell_data);
437 };
440 };
438 };
441 };
439 };
442 };
440
443
441
444
442 Notebook.prototype.toJSON = function () {
445 Notebook.prototype.toJSON = function () {
443 var cells = this.cells();
446 var cells = this.cells();
444 var ncells = cells.length;
447 var ncells = cells.length;
445 cell_array = new Array(ncells);
448 cell_array = new Array(ncells);
446 for (var i=0; i<ncells; i++) {
449 for (var i=0; i<ncells; i++) {
447 cell_array[i] = cells[i].toJSON();
450 cell_array[i] = cells[i].toJSON();
448 };
451 };
449 json = {
452 json = {
450 cells : cell_array
453 cells : cell_array
451 };
454 };
452 return json
455 return json
453 };
456 };
454
457
455
458
456 Notebook.prototype.test_filename = function (filename) {
459 Notebook.prototype.test_filename = function (filename) {
457 if (this.notebook_filename_re.test(filename)) {
460 if (this.notebook_filename_re.test(filename)) {
458 return true;
461 return true;
459 } else {
462 } else {
460 var bad_filename = $('<div/>');
463 var bad_filename = $('<div/>');
461 bad_filename.html(
464 bad_filename.html(
462 "The filename you entered (" + filename + ") is not valid. Notebook filenames must have the following form: foo.ipynb"
465 "The filename you entered (" + filename + ") is not valid. Notebook filenames must have the following form: foo.ipynb"
463 );
466 );
464 bad_filename.dialog({title: 'Invalid filename', modal: true});
467 bad_filename.dialog({title: 'Invalid filename', modal: true});
465 return false;
468 return false;
466 };
469 };
467 };
470 };
468
471
469 Notebook.prototype.save_notebook = function (filename) {
472 Notebook.prototype.save_notebook = function (filename) {
470 this.filename = filename || this.filename || '';
473 this.filename = filename || this.filename || '';
471 if (this.filename === '') {
474 if (this.filename === '') {
472 var no_filename = $('<div/>');
475 var no_filename = $('<div/>');
473 no_filename.html(
476 no_filename.html(
474 "This notebook has no filename, please specify a filename of the form: foo.ipynb"
477 "This notebook has no filename, please specify a filename of the form: foo.ipynb"
475 );
478 );
476 no_filename.dialog({title: 'Missing filename', modal: true});
479 no_filename.dialog({title: 'Missing filename', modal: true});
477 return;
480 return;
478 }
481 }
479 if (!this.test_filename(this.filename)) {return;}
482 if (!this.test_filename(this.filename)) {return;}
480 var thedata = this.toJSON();
483 var thedata = this.toJSON();
481 var settings = {
484 var settings = {
482 processData : false,
485 processData : false,
483 cache : false,
486 cache : false,
484 type : "PUT",
487 type : "PUT",
485 data : JSON.stringify(thedata),
488 data : JSON.stringify(thedata),
486 success : function (data, status, xhr) {console.log(data);}
489 success : function (data, status, xhr) {console.log(data);}
487 };
490 };
488 $.ajax("/notebooks/" + this.filename, settings);
491 $.ajax("/notebooks/" + this.filename, settings);
489 };
492 };
490
493
491
494
492 Notebook.prototype.load_notebook = function (filename) {
495 Notebook.prototype.load_notebook = function (filename) {
493 if (!this.test_filename(filename)) {return;}
496 if (!this.test_filename(filename)) {return;}
494 var that = this;
497 var that = this;
495 // We do the call with settings so we can set cache to false.
498 // We do the call with settings so we can set cache to false.
496 var settings = {
499 var settings = {
497 processData : false,
500 processData : false,
498 cache : false,
501 cache : false,
499 type : "GET",
502 type : "GET",
500 dataType : "json",
503 dataType : "json",
501 success : function (data, status, xhr) {
504 success : function (data, status, xhr) {
502 that.fromJSON(data);
505 that.fromJSON(data);
503 that.filename = filename;
506 that.filename = filename;
504 that.kernel.restart();
507 that.kernel.restart();
505 }
508 }
506 };
509 };
507 $.ajax("/notebooks/" + filename, settings);
510 $.ajax("/notebooks/" + filename, settings);
508 }
511 }
509
512
510 IPython.Notebook = Notebook;
513 IPython.Notebook = Notebook;
511
514
512 return IPython;
515 return IPython;
513
516
514 }(IPython));
517 }(IPython));
515
518
General Comments 0
You need to be logged in to leave comments. Login now