##// END OF EJS Templates
Backport PR #4064: Store default codemirror mode in only 1 place...
MinRK -
Show More
@@ -1,335 +1,340 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // Cell
10 10 //============================================================================
11 11 /**
12 12 * An extendable module that provide base functionnality to create cell for notebook.
13 13 * @module IPython
14 14 * @namespace IPython
15 15 * @submodule Cell
16 16 */
17 17
18 18 var IPython = (function (IPython) {
19 19
20 20 var utils = IPython.utils;
21 21
22 22 /**
23 23 * The Base `Cell` class from which to inherit
24 24 * @class Cell
25 25 **/
26 26
27 27 /*
28 28 * @constructor
29 29 *
30 30 * @param {object|undefined} [options]
31 31 * @param [options.cm_config] {object} config to pass to CodeMirror, will extend default parameters
32 32 */
33 33 var Cell = function (options) {
34 34
35 35 options = this.mergeopt(Cell, options)
36 36 // superclass default overwrite our default
37 37
38 38 this.placeholder = options.placeholder || '';
39 39 this.read_only = options.cm_config.readOnly;
40 40 this.selected = false;
41 41 this.element = null;
42 42 this.metadata = {};
43 43 // load this from metadata later ?
44 44 this.user_highlight = 'auto';
45 45 this.cm_config = options.cm_config;
46 46 this.create_element();
47 47 if (this.element !== null) {
48 48 this.element.data("cell", this);
49 49 this.bind_events();
50 50 }
51 51 this.cell_id = utils.uuid();
52 52 this._options = options;
53 53 };
54 54
55 55 Cell.options_default = {
56 56 cm_config : {
57 57 indentUnit : 4,
58 58 readOnly: false,
59 59 theme: "default"
60 60 }
61 61 };
62 62
63 63 // FIXME: Workaround CM Bug #332 (Safari segfault on drag)
64 64 // by disabling drag/drop altogether on Safari
65 65 // https://github.com/marijnh/CodeMirror/issues/332
66 66
67 67 if (utils.browser[0] == "Safari") {
68 68 Cell.options_default.cm_config.dragDrop = false;
69 69 }
70 70
71 71 Cell.prototype.mergeopt = function(_class, options, overwrite){
72 72 overwrite = overwrite || {};
73 73 return $.extend(true, {}, _class.options_default, options, overwrite)
74 74
75 75 }
76 76
77 77
78 78
79 79 /**
80 80 * Empty. Subclasses must implement create_element.
81 81 * This should contain all the code to create the DOM element in notebook
82 82 * and will be called by Base Class constructor.
83 83 * @method create_element
84 84 */
85 85 Cell.prototype.create_element = function () {
86 86 };
87 87
88 88
89 89 /**
90 90 * Subclasses can implement override bind_events.
91 91 * Be carefull to call the parent method when overwriting as it fires event.
92 92 * this will be triggerd after create_element in constructor.
93 93 * @method bind_events
94 94 */
95 95 Cell.prototype.bind_events = function () {
96 96 var that = this;
97 97 // We trigger events so that Cell doesn't have to depend on Notebook.
98 98 that.element.click(function (event) {
99 99 if (that.selected === false) {
100 100 $([IPython.events]).trigger('select.Cell', {'cell':that});
101 101 }
102 102 });
103 103 that.element.focusin(function (event) {
104 104 if (that.selected === false) {
105 105 $([IPython.events]).trigger('select.Cell', {'cell':that});
106 106 }
107 107 });
108 108 if (this.code_mirror) {
109 109 this.code_mirror.on("change", function(cm, change) {
110 110 $([IPython.events]).trigger("set_dirty.Notebook", {value: true});
111 111 });
112 112 }
113 113 };
114 114
115 115 /**
116 116 * Triger typsetting of math by mathjax on current cell element
117 117 * @method typeset
118 118 */
119 119 Cell.prototype.typeset = function () {
120 120 if (window.MathJax){
121 121 var cell_math = this.element.get(0);
122 122 MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]);
123 123 }
124 124 };
125 125
126 126 /**
127 127 * should be triggerd when cell is selected
128 128 * @method select
129 129 */
130 130 Cell.prototype.select = function () {
131 131 this.element.addClass('selected');
132 132 this.selected = true;
133 133 };
134 134
135 135
136 136 /**
137 137 * should be triggerd when cell is unselected
138 138 * @method unselect
139 139 */
140 140 Cell.prototype.unselect = function () {
141 141 this.element.removeClass('selected');
142 142 this.selected = false;
143 143 };
144 144
145 145 /**
146 146 * should be overritten by subclass
147 147 * @method get_text
148 148 */
149 149 Cell.prototype.get_text = function () {
150 150 };
151 151
152 152 /**
153 153 * should be overritten by subclass
154 154 * @method set_text
155 155 * @param {string} text
156 156 */
157 157 Cell.prototype.set_text = function (text) {
158 158 };
159 159
160 160 /**
161 161 * Refresh codemirror instance
162 162 * @method refresh
163 163 */
164 164 Cell.prototype.refresh = function () {
165 165 this.code_mirror.refresh();
166 166 };
167 167
168 168
169 169 /**
170 170 * should be overritten by subclass
171 171 * @method edit
172 172 **/
173 173 Cell.prototype.edit = function () {
174 174 };
175 175
176 176
177 177 /**
178 178 * should be overritten by subclass
179 179 * @method render
180 180 **/
181 181 Cell.prototype.render = function () {
182 182 };
183 183
184 184 /**
185 185 * should be overritten by subclass
186 186 * serialise cell to json.
187 187 * @method toJSON
188 188 **/
189 189 Cell.prototype.toJSON = function () {
190 190 var data = {};
191 191 data.metadata = this.metadata;
192 192 return data;
193 193 };
194 194
195 195
196 196 /**
197 197 * should be overritten by subclass
198 198 * @method fromJSON
199 199 **/
200 200 Cell.prototype.fromJSON = function (data) {
201 201 if (data.metadata !== undefined) {
202 202 this.metadata = data.metadata;
203 203 }
204 204 this.celltoolbar.rebuild();
205 205 };
206 206
207 207
208 208 /**
209 209 * can the cell be splitted in 2 cells.
210 210 * @method is_splittable
211 211 **/
212 212 Cell.prototype.is_splittable = function () {
213 213 return true;
214 214 };
215 215
216 216
217 217 /**
218 218 * @return {String} - the text before the cursor
219 219 * @method get_pre_cursor
220 220 **/
221 221 Cell.prototype.get_pre_cursor = function () {
222 222 var cursor = this.code_mirror.getCursor();
223 223 var text = this.code_mirror.getRange({line:0, ch:0}, cursor);
224 224 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
225 225 return text;
226 226 }
227 227
228 228
229 229 /**
230 230 * @return {String} - the text after the cursor
231 231 * @method get_post_cursor
232 232 **/
233 233 Cell.prototype.get_post_cursor = function () {
234 234 var cursor = this.code_mirror.getCursor();
235 235 var last_line_num = this.code_mirror.lineCount()-1;
236 236 var last_line_len = this.code_mirror.getLine(last_line_num).length;
237 237 var end = {line:last_line_num, ch:last_line_len}
238 238 var text = this.code_mirror.getRange(cursor, end);
239 239 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
240 240 return text;
241 241 };
242 242
243 243 /**
244 244 * Show/Hide CodeMirror LineNumber
245 245 * @method show_line_numbers
246 246 *
247 247 * @param value {Bool} show (true), or hide (false) the line number in CodeMirror
248 248 **/
249 249 Cell.prototype.show_line_numbers = function (value) {
250 250 this.code_mirror.setOption('lineNumbers', value);
251 251 this.code_mirror.refresh();
252 252 };
253 253
254 254 /**
255 255 * Toggle CodeMirror LineNumber
256 256 * @method toggle_line_numbers
257 257 **/
258 258 Cell.prototype.toggle_line_numbers = function () {
259 259 var val = this.code_mirror.getOption('lineNumbers');
260 260 this.show_line_numbers(!val);
261 261 };
262 262
263 263 /**
264 264 * Force codemirror highlight mode
265 265 * @method force_highlight
266 266 * @param {object} - CodeMirror mode
267 267 **/
268 268 Cell.prototype.force_highlight = function(mode) {
269 269 this.user_highlight = mode;
270 270 this.auto_highlight();
271 271 };
272 272
273 273 /**
274 274 * Try to autodetect cell highlight mode, or use selected mode
275 275 * @methods _auto_highlight
276 276 * @private
277 277 * @param {String|object|undefined} - CodeMirror mode | 'auto'
278 278 **/
279 279 Cell.prototype._auto_highlight = function (modes) {
280 280 //Here we handle manually selected modes
281 281 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
282 282 {
283 283 var mode = this.user_highlight;
284 284 CodeMirror.autoLoadMode(this.code_mirror, mode);
285 285 this.code_mirror.setOption('mode', mode);
286 286 return;
287 287 }
288 288 var first_line = this.code_mirror.getLine(0);
289 289 // loop on every pairs
290 290 for( var mode in modes) {
291 291 var regs = modes[mode]['reg'];
292 292 // only one key every time but regexp can't be keys...
293 293 for(var reg in regs ) {
294 294 // here we handle non magic_modes
295 295 if(first_line.match(regs[reg]) != null) {
296 296 if (mode.search('magic_') != 0) {
297 297 this.code_mirror.setOption('mode', mode);
298 298 CodeMirror.autoLoadMode(this.code_mirror, mode);
299 299 return;
300 300 }
301 301 var open = modes[mode]['open']|| "%%";
302 302 var close = modes[mode]['close']|| "%%end";
303 303 var mmode = mode;
304 304 mode = mmode.substr(6);
305 305 CodeMirror.autoLoadMode(this.code_mirror, mode);
306 306 // create on the fly a mode that swhitch between
307 307 // plain/text and smth else otherwise `%%` is
308 308 // source of some highlight issues.
309 309 // we use patchedGetMode to circumvent a bug in CM
310 310 CodeMirror.defineMode(mmode , function(config) {
311 311 return CodeMirror.multiplexingMode(
312 312 CodeMirror.patchedGetMode(config, 'text/plain'),
313 313 // always set someting on close
314 314 {open: open, close: close,
315 315 mode: CodeMirror.patchedGetMode(config, mode),
316 316 delimStyle: "delimit"
317 317 }
318 318 );
319 319 });
320 320 this.code_mirror.setOption('mode', mmode);
321 321 return;
322 322 }
323 323 }
324 324 }
325 // fallback on default (python)
326 var default_mode = this.default_mode || 'text/plain';
325 // fallback on default
326 var default_mode
327 try {
328 default_mode = this._options.cm_config.mode;
329 } catch(e) {
330 default_mode = 'text/plain';
331 }
327 332 this.code_mirror.setOption('mode', default_mode);
328 333 };
329 334
330 335 IPython.Cell = Cell;
331 336
332 337 return IPython;
333 338
334 339 }(IPython));
335 340
@@ -1,443 +1,442 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // CodeCell
10 10 //============================================================================
11 11 /**
12 12 * An extendable module that provide base functionnality to create cell for notebook.
13 13 * @module IPython
14 14 * @namespace IPython
15 15 * @submodule CodeCell
16 16 */
17 17
18 18
19 19 /* local util for codemirror */
20 20 var posEq = function(a, b) {return a.line == b.line && a.ch == b.ch;}
21 21
22 22 /**
23 23 *
24 24 * function to delete until previous non blanking space character
25 25 * or first multiple of 4 tabstop.
26 26 * @private
27 27 */
28 28 CodeMirror.commands.delSpaceToPrevTabStop = function(cm){
29 29 var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
30 30 if (!posEq(from, to)) {cm.replaceRange("", from, to); return}
31 31 var cur = cm.getCursor(), line = cm.getLine(cur.line);
32 32 var tabsize = cm.getOption('tabSize');
33 33 var chToPrevTabStop = cur.ch-(Math.ceil(cur.ch/tabsize)-1)*tabsize;
34 34 var from = {ch:cur.ch-chToPrevTabStop,line:cur.line}
35 35 var select = cm.getRange(from,cur)
36 36 if( select.match(/^\ +$/) != null){
37 37 cm.replaceRange("",from,cur)
38 38 } else {
39 39 cm.deleteH(-1,"char")
40 40 }
41 41 };
42 42
43 43
44 44 var IPython = (function (IPython) {
45 45 "use strict";
46 46
47 47 var utils = IPython.utils;
48 48 var key = IPython.utils.keycodes;
49 49
50 50 /**
51 51 * A Cell conceived to write code.
52 52 *
53 53 * The kernel doesn't have to be set at creation time, in that case
54 54 * it will be null and set_kernel has to be called later.
55 55 * @class CodeCell
56 56 * @extends IPython.Cell
57 57 *
58 58 * @constructor
59 59 * @param {Object|null} kernel
60 60 * @param {object|undefined} [options]
61 61 * @param [options.cm_config] {object} config to pass to CodeMirror
62 62 */
63 63 var CodeCell = function (kernel, options) {
64 64 this.kernel = kernel || null;
65 65 this.code_mirror = null;
66 66 this.input_prompt_number = null;
67 67 this.collapsed = false;
68 this.default_mode = 'ipython';
69 68 this.cell_type = "code";
70 69
71 70
72 71 var cm_overwrite_options = {
73 72 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
74 73 };
75 74
76 75 options = this.mergeopt(CodeCell, options, {cm_config:cm_overwrite_options});
77 76
78 77 IPython.Cell.apply(this,[options]);
79 78
80 79 var that = this;
81 80 this.element.focusout(
82 81 function() { that.auto_highlight(); }
83 82 );
84 83 };
85 84
86 85 CodeCell.options_default = {
87 86 cm_config : {
88 87 extraKeys: {
89 88 "Tab" : "indentMore",
90 89 "Shift-Tab" : "indentLess",
91 90 "Backspace" : "delSpaceToPrevTabStop",
92 91 "Cmd-/" : "toggleComment",
93 92 "Ctrl-/" : "toggleComment"
94 93 },
95 94 mode: 'ipython',
96 95 theme: 'ipython',
97 96 matchBrackets: true
98 97 }
99 98 };
100 99
101 100
102 101 CodeCell.prototype = new IPython.Cell();
103 102
104 103 /**
105 104 * @method auto_highlight
106 105 */
107 106 CodeCell.prototype.auto_highlight = function () {
108 107 this._auto_highlight(IPython.config.cell_magic_highlight)
109 108 };
110 109
111 110 /** @method create_element */
112 111 CodeCell.prototype.create_element = function () {
113 112 IPython.Cell.prototype.create_element.apply(this, arguments);
114 113
115 114 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell');
116 115 cell.attr('tabindex','2');
117 116
118 117 this.celltoolbar = new IPython.CellToolbar(this);
119 118
120 119 var input = $('<div></div>').addClass('input');
121 120 var vbox = $('<div/>').addClass('vbox box-flex1')
122 121 input.append($('<div/>').addClass('prompt input_prompt'));
123 122 vbox.append(this.celltoolbar.element);
124 123 var input_area = $('<div/>').addClass('input_area');
125 124 this.code_mirror = CodeMirror(input_area.get(0), this.cm_config);
126 125 $(this.code_mirror.getInputField()).attr("spellcheck", "false");
127 126 vbox.append(input_area);
128 127 input.append(vbox);
129 128 var output = $('<div></div>');
130 129 cell.append(input).append(output);
131 130 this.element = cell;
132 131 this.output_area = new IPython.OutputArea(output, true);
133 132
134 133 // construct a completer only if class exist
135 134 // otherwise no print view
136 135 if (IPython.Completer !== undefined)
137 136 {
138 137 this.completer = new IPython.Completer(this);
139 138 }
140 139 };
141 140
142 141 /**
143 142 * This method gets called in CodeMirror's onKeyDown/onKeyPress
144 143 * handlers and is used to provide custom key handling. Its return
145 144 * value is used to determine if CodeMirror should ignore the event:
146 145 * true = ignore, false = don't ignore.
147 146 * @method handle_codemirror_keyevent
148 147 */
149 148 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
150 149
151 150 var that = this;
152 151 // whatever key is pressed, first, cancel the tooltip request before
153 152 // they are sent, and remove tooltip if any, except for tab again
154 153 if (event.type === 'keydown' && event.which != key.TAB ) {
155 154 IPython.tooltip.remove_and_cancel_tooltip();
156 155 };
157 156
158 157 var cur = editor.getCursor();
159 158 if (event.keyCode === key.ENTER){
160 159 this.auto_highlight();
161 160 }
162 161
163 162 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
164 163 // Always ignore shift-enter in CodeMirror as we handle it.
165 164 return true;
166 165 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
167 166 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
168 167 // browser and keyboard layout !
169 168 // Pressing '(' , request tooltip, don't forget to reappend it
170 169 // The second argument says to hide the tooltip if the docstring
171 170 // is actually empty
172 171 IPython.tooltip.pending(that, true);
173 172 } else if (event.which === key.UPARROW && event.type === 'keydown') {
174 173 // If we are not at the top, let CM handle the up arrow and
175 174 // prevent the global keydown handler from handling it.
176 175 if (!that.at_top()) {
177 176 event.stop();
178 177 return false;
179 178 } else {
180 179 return true;
181 180 };
182 181 } else if (event.which === key.ESC) {
183 182 IPython.tooltip.remove_and_cancel_tooltip(true);
184 183 return true;
185 184 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
186 185 // If we are not at the bottom, let CM handle the down arrow and
187 186 // prevent the global keydown handler from handling it.
188 187 if (!that.at_bottom()) {
189 188 event.stop();
190 189 return false;
191 190 } else {
192 191 return true;
193 192 };
194 193 } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
195 194 if (editor.somethingSelected()){
196 195 var anchor = editor.getCursor("anchor");
197 196 var head = editor.getCursor("head");
198 197 if( anchor.line != head.line){
199 198 return false;
200 199 }
201 200 }
202 201 IPython.tooltip.request(that);
203 202 event.stop();
204 203 return true;
205 204 } else if (event.keyCode === key.TAB && event.type == 'keydown') {
206 205 // Tab completion.
207 206 //Do not trim here because of tooltip
208 207 if (editor.somethingSelected()){return false}
209 208 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur);
210 209 if (pre_cursor.trim() === "") {
211 210 // Don't autocomplete if the part of the line before the cursor
212 211 // is empty. In this case, let CodeMirror handle indentation.
213 212 return false;
214 213 } else if ((pre_cursor.substr(-1) === "("|| pre_cursor.substr(-1) === " ") && IPython.config.tooltip_on_tab ) {
215 214 IPython.tooltip.request(that);
216 215 // Prevent the event from bubbling up.
217 216 event.stop();
218 217 // Prevent CodeMirror from handling the tab.
219 218 return true;
220 219 } else {
221 220 event.stop();
222 221 this.completer.startCompletion();
223 222 return true;
224 223 };
225 224 } else {
226 225 // keypress/keyup also trigger on TAB press, and we don't want to
227 226 // use those to disable tab completion.
228 227 return false;
229 228 };
230 229 return false;
231 230 };
232 231
233 232
234 233 // Kernel related calls.
235 234
236 235 CodeCell.prototype.set_kernel = function (kernel) {
237 236 this.kernel = kernel;
238 237 }
239 238
240 239 /**
241 240 * Execute current code cell to the kernel
242 241 * @method execute
243 242 */
244 243 CodeCell.prototype.execute = function () {
245 244 this.output_area.clear_output(true, true, true);
246 245 this.set_input_prompt('*');
247 246 this.element.addClass("running");
248 247 var callbacks = {
249 248 'execute_reply': $.proxy(this._handle_execute_reply, this),
250 249 'output': $.proxy(this.output_area.handle_output, this.output_area),
251 250 'clear_output': $.proxy(this.output_area.handle_clear_output, this.output_area),
252 251 'set_next_input': $.proxy(this._handle_set_next_input, this),
253 252 'input_request': $.proxy(this._handle_input_request, this)
254 253 };
255 254 var msg_id = this.kernel.execute(this.get_text(), callbacks, {silent: false, store_history: true});
256 255 };
257 256
258 257 /**
259 258 * @method _handle_execute_reply
260 259 * @private
261 260 */
262 261 CodeCell.prototype._handle_execute_reply = function (content) {
263 262 this.set_input_prompt(content.execution_count);
264 263 this.element.removeClass("running");
265 264 $([IPython.events]).trigger('set_dirty.Notebook', {value: true});
266 265 }
267 266
268 267 /**
269 268 * @method _handle_set_next_input
270 269 * @private
271 270 */
272 271 CodeCell.prototype._handle_set_next_input = function (text) {
273 272 var data = {'cell': this, 'text': text}
274 273 $([IPython.events]).trigger('set_next_input.Notebook', data);
275 274 }
276 275
277 276 /**
278 277 * @method _handle_input_request
279 278 * @private
280 279 */
281 280 CodeCell.prototype._handle_input_request = function (content) {
282 281 this.output_area.append_raw_input(content);
283 282 }
284 283
285 284
286 285 // Basic cell manipulation.
287 286
288 287 CodeCell.prototype.select = function () {
289 288 IPython.Cell.prototype.select.apply(this);
290 289 this.code_mirror.refresh();
291 290 this.code_mirror.focus();
292 291 this.auto_highlight();
293 292 // We used to need an additional refresh() after the focus, but
294 293 // it appears that this has been fixed in CM. This bug would show
295 294 // up on FF when a newly loaded markdown cell was edited.
296 295 };
297 296
298 297
299 298 CodeCell.prototype.select_all = function () {
300 299 var start = {line: 0, ch: 0};
301 300 var nlines = this.code_mirror.lineCount();
302 301 var last_line = this.code_mirror.getLine(nlines-1);
303 302 var end = {line: nlines-1, ch: last_line.length};
304 303 this.code_mirror.setSelection(start, end);
305 304 };
306 305
307 306
308 307 CodeCell.prototype.collapse = function () {
309 308 this.collapsed = true;
310 309 this.output_area.collapse();
311 310 };
312 311
313 312
314 313 CodeCell.prototype.expand = function () {
315 314 this.collapsed = false;
316 315 this.output_area.expand();
317 316 };
318 317
319 318
320 319 CodeCell.prototype.toggle_output = function () {
321 320 this.collapsed = Boolean(1 - this.collapsed);
322 321 this.output_area.toggle_output();
323 322 };
324 323
325 324
326 325 CodeCell.prototype.toggle_output_scroll = function () {
327 326 this.output_area.toggle_scroll();
328 327 };
329 328
330 329
331 330 CodeCell.input_prompt_classical = function (prompt_value, lines_number) {
332 331 var ns = prompt_value || "&nbsp;";
333 332 return 'In&nbsp;[' + ns + ']:'
334 333 };
335 334
336 335 CodeCell.input_prompt_continuation = function (prompt_value, lines_number) {
337 336 var html = [CodeCell.input_prompt_classical(prompt_value, lines_number)];
338 337 for(var i=1; i < lines_number; i++){html.push(['...:'])};
339 338 return html.join('</br>')
340 339 };
341 340
342 341 CodeCell.input_prompt_function = CodeCell.input_prompt_classical;
343 342
344 343
345 344 CodeCell.prototype.set_input_prompt = function (number) {
346 345 var nline = 1
347 346 if( this.code_mirror != undefined) {
348 347 nline = this.code_mirror.lineCount();
349 348 }
350 349 this.input_prompt_number = number;
351 350 var prompt_html = CodeCell.input_prompt_function(this.input_prompt_number, nline);
352 351 this.element.find('div.input_prompt').html(prompt_html);
353 352 };
354 353
355 354
356 355 CodeCell.prototype.clear_input = function () {
357 356 this.code_mirror.setValue('');
358 357 };
359 358
360 359
361 360 CodeCell.prototype.get_text = function () {
362 361 return this.code_mirror.getValue();
363 362 };
364 363
365 364
366 365 CodeCell.prototype.set_text = function (code) {
367 366 return this.code_mirror.setValue(code);
368 367 };
369 368
370 369
371 370 CodeCell.prototype.at_top = function () {
372 371 var cursor = this.code_mirror.getCursor();
373 372 if (cursor.line === 0 && cursor.ch === 0) {
374 373 return true;
375 374 } else {
376 375 return false;
377 376 }
378 377 };
379 378
380 379
381 380 CodeCell.prototype.at_bottom = function () {
382 381 var cursor = this.code_mirror.getCursor();
383 382 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
384 383 return true;
385 384 } else {
386 385 return false;
387 386 }
388 387 };
389 388
390 389
391 390 CodeCell.prototype.clear_output = function (stdout, stderr, other) {
392 391 this.output_area.clear_output(stdout, stderr, other);
393 392 };
394 393
395 394
396 395 // JSON serialization
397 396
398 397 CodeCell.prototype.fromJSON = function (data) {
399 398 IPython.Cell.prototype.fromJSON.apply(this, arguments);
400 399 if (data.cell_type === 'code') {
401 400 if (data.input !== undefined) {
402 401 this.set_text(data.input);
403 402 // make this value the starting point, so that we can only undo
404 403 // to this state, instead of a blank cell
405 404 this.code_mirror.clearHistory();
406 405 this.auto_highlight();
407 406 }
408 407 if (data.prompt_number !== undefined) {
409 408 this.set_input_prompt(data.prompt_number);
410 409 } else {
411 410 this.set_input_prompt();
412 411 };
413 412 this.output_area.fromJSON(data.outputs);
414 413 if (data.collapsed !== undefined) {
415 414 if (data.collapsed) {
416 415 this.collapse();
417 416 } else {
418 417 this.expand();
419 418 };
420 419 };
421 420 };
422 421 };
423 422
424 423
425 424 CodeCell.prototype.toJSON = function () {
426 425 var data = IPython.Cell.prototype.toJSON.apply(this);
427 426 data.input = this.get_text();
428 427 data.cell_type = 'code';
429 428 if (this.input_prompt_number) {
430 429 data.prompt_number = this.input_prompt_number;
431 430 };
432 431 var outputs = this.output_area.toJSON();
433 432 data.outputs = outputs;
434 433 data.language = 'python';
435 434 data.collapsed = this.collapsed;
436 435 return data;
437 436 };
438 437
439 438
440 439 IPython.CodeCell = CodeCell;
441 440
442 441 return IPython;
443 442 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now