##// END OF EJS Templates
use show method in toggle method
Matthias BUSSONNIER -
Show More
@@ -1,325 +1,321 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // Cell
9 // Cell
10 //============================================================================
10 //============================================================================
11 /**
11 /**
12 * An extendable module that provide base functionnality to create cell for notebook.
12 * An extendable module that provide base functionnality to create cell for notebook.
13 * @module IPython
13 * @module IPython
14 * @namespace IPython
14 * @namespace IPython
15 * @submodule Cell
15 * @submodule Cell
16 */
16 */
17
17
18 var IPython = (function (IPython) {
18 var IPython = (function (IPython) {
19
19
20 var utils = IPython.utils;
20 var utils = IPython.utils;
21
21
22 /**
22 /**
23 * The Base `Cell` class from which to inherit
23 * The Base `Cell` class from which to inherit
24 * @class Cell
24 * @class Cell
25 */
25 */
26
26
27 /*
27 /*
28 * @constructor
28 * @constructor
29 */
29 */
30 var Cell = function () {
30 var Cell = function () {
31 this.placeholder = this.placeholder || '';
31 this.placeholder = this.placeholder || '';
32 this.read_only = false;
32 this.read_only = false;
33 this.selected = false;
33 this.selected = false;
34 this.element = null;
34 this.element = null;
35 this.metadata = {};
35 this.metadata = {};
36 // load this from metadata later ?
36 // load this from metadata later ?
37 this.user_highlight = 'auto';
37 this.user_highlight = 'auto';
38 this.create_element();
38 this.create_element();
39 if (this.element !== null) {
39 if (this.element !== null) {
40 this.element.data("cell", this);
40 this.element.data("cell", this);
41 this.bind_events();
41 this.bind_events();
42 }
42 }
43 this.cell_id = utils.uuid();
43 this.cell_id = utils.uuid();
44 };
44 };
45
45
46
46
47 /**
47 /**
48 * Empty. Subclasses must implement create_element.
48 * Empty. Subclasses must implement create_element.
49 * This should contain all the code to create the DOM element in notebook
49 * This should contain all the code to create the DOM element in notebook
50 * and will be called by Base Class constructor.
50 * and will be called by Base Class constructor.
51 * @method create_element
51 * @method create_element
52 */
52 */
53 Cell.prototype.create_element = function () {
53 Cell.prototype.create_element = function () {
54 };
54 };
55
55
56
56
57 /**
57 /**
58 * Subclasses can implement override bind_events.
58 * Subclasses can implement override bind_events.
59 * Be carefull to call the parent method when overwriting as it fires event.
59 * Be carefull to call the parent method when overwriting as it fires event.
60 * this will be triggerd after create_element in constructor.
60 * this will be triggerd after create_element in constructor.
61 * @method bind_events
61 * @method bind_events
62 */
62 */
63 Cell.prototype.bind_events = function () {
63 Cell.prototype.bind_events = function () {
64 var that = this;
64 var that = this;
65 // We trigger events so that Cell doesn't have to depend on Notebook.
65 // We trigger events so that Cell doesn't have to depend on Notebook.
66 that.element.click(function (event) {
66 that.element.click(function (event) {
67 if (that.selected === false) {
67 if (that.selected === false) {
68 $([IPython.events]).trigger('select.Cell', {'cell':that});
68 $([IPython.events]).trigger('select.Cell', {'cell':that});
69 }
69 }
70 });
70 });
71 that.element.focusin(function (event) {
71 that.element.focusin(function (event) {
72 if (that.selected === false) {
72 if (that.selected === false) {
73 $([IPython.events]).trigger('select.Cell', {'cell':that});
73 $([IPython.events]).trigger('select.Cell', {'cell':that});
74 }
74 }
75 });
75 });
76 };
76 };
77
77
78 /**
78 /**
79 * Triger typsetting of math by mathjax on current cell element
79 * Triger typsetting of math by mathjax on current cell element
80 * @method typeset
80 * @method typeset
81 */
81 */
82 Cell.prototype.typeset = function () {
82 Cell.prototype.typeset = function () {
83 if (window.MathJax){
83 if (window.MathJax){
84 var cell_math = this.element.get(0);
84 var cell_math = this.element.get(0);
85 MathJax.Hub.Queue(["Typeset",MathJax.Hub,cell_math]);
85 MathJax.Hub.Queue(["Typeset",MathJax.Hub,cell_math]);
86 }
86 }
87 };
87 };
88
88
89 /**
89 /**
90 * should be triggerd when cell is selected
90 * should be triggerd when cell is selected
91 * @method select
91 * @method select
92 */
92 */
93 Cell.prototype.select = function () {
93 Cell.prototype.select = function () {
94 this.element.addClass('selected');
94 this.element.addClass('selected');
95 this.selected = true;
95 this.selected = true;
96 };
96 };
97
97
98
98
99 /**
99 /**
100 * should be triggerd when cell is unselected
100 * should be triggerd when cell is unselected
101 * @method unselect
101 * @method unselect
102 */
102 */
103 Cell.prototype.unselect = function () {
103 Cell.prototype.unselect = function () {
104 this.element.removeClass('selected');
104 this.element.removeClass('selected');
105 this.selected = false;
105 this.selected = false;
106 };
106 };
107
107
108 /**
108 /**
109 * should be overritten by subclass
109 * should be overritten by subclass
110 * @method get_text
110 * @method get_text
111 */
111 */
112 Cell.prototype.get_text = function () {
112 Cell.prototype.get_text = function () {
113 };
113 };
114
114
115 /**
115 /**
116 * should be overritten by subclass
116 * should be overritten by subclass
117 * @method set_text
117 * @method set_text
118 * @param {string} text
118 * @param {string} text
119 */
119 */
120 Cell.prototype.set_text = function (text) {
120 Cell.prototype.set_text = function (text) {
121 };
121 };
122
122
123 /**
123 /**
124 * Refresh codemirror instance
124 * Refresh codemirror instance
125 * @method refresh
125 * @method refresh
126 */
126 */
127 Cell.prototype.refresh = function () {
127 Cell.prototype.refresh = function () {
128 this.code_mirror.refresh();
128 this.code_mirror.refresh();
129 };
129 };
130
130
131
131
132 /**
132 /**
133 * should be overritten by subclass
133 * should be overritten by subclass
134 * @method edit
134 * @method edit
135 **/
135 **/
136 Cell.prototype.edit = function () {
136 Cell.prototype.edit = function () {
137 };
137 };
138
138
139
139
140 /**
140 /**
141 * should be overritten by subclass
141 * should be overritten by subclass
142 * @method render
142 * @method render
143 **/
143 **/
144 Cell.prototype.render = function () {
144 Cell.prototype.render = function () {
145 };
145 };
146
146
147 /**
147 /**
148 * should be overritten by subclass
148 * should be overritten by subclass
149 * serialise cell to json.
149 * serialise cell to json.
150 * @method toJSON
150 * @method toJSON
151 **/
151 **/
152 Cell.prototype.toJSON = function () {
152 Cell.prototype.toJSON = function () {
153 var data = {};
153 var data = {};
154 data.metadata = this.metadata;
154 data.metadata = this.metadata;
155 return data;
155 return data;
156 };
156 };
157
157
158
158
159 /**
159 /**
160 * should be overritten by subclass
160 * should be overritten by subclass
161 * @method fromJSON
161 * @method fromJSON
162 **/
162 **/
163 Cell.prototype.fromJSON = function (data) {
163 Cell.prototype.fromJSON = function (data) {
164 if (data.metadata !== undefined) {
164 if (data.metadata !== undefined) {
165 this.metadata = data.metadata;
165 this.metadata = data.metadata;
166 }
166 }
167 this.celltoolbar.rebuild();
167 this.celltoolbar.rebuild();
168 };
168 };
169
169
170
170
171 /**
171 /**
172 * can the cell be splitted in 2 cells.
172 * can the cell be splitted in 2 cells.
173 * @method is_splittable
173 * @method is_splittable
174 **/
174 **/
175 Cell.prototype.is_splittable = function () {
175 Cell.prototype.is_splittable = function () {
176 return true;
176 return true;
177 };
177 };
178
178
179
179
180 /**
180 /**
181 * @return {String} - the text before the cursor
181 * @return {String} - the text before the cursor
182 * @method get_pre_cursor
182 * @method get_pre_cursor
183 **/
183 **/
184 Cell.prototype.get_pre_cursor = function () {
184 Cell.prototype.get_pre_cursor = function () {
185 var cursor = this.code_mirror.getCursor();
185 var cursor = this.code_mirror.getCursor();
186 var text = this.code_mirror.getRange({line:0,ch:0}, cursor);
186 var text = this.code_mirror.getRange({line:0,ch:0}, cursor);
187 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
187 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
188 return text;
188 return text;
189 }
189 }
190
190
191
191
192 /**
192 /**
193 * @return {String} - the text after the cursor
193 * @return {String} - the text after the cursor
194 * @method get_post_cursor
194 * @method get_post_cursor
195 **/
195 **/
196 Cell.prototype.get_post_cursor = function () {
196 Cell.prototype.get_post_cursor = function () {
197 var cursor = this.code_mirror.getCursor();
197 var cursor = this.code_mirror.getCursor();
198 var last_line_num = this.code_mirror.lineCount()-1;
198 var last_line_num = this.code_mirror.lineCount()-1;
199 var last_line_len = this.code_mirror.getLine(last_line_num).length;
199 var last_line_len = this.code_mirror.getLine(last_line_num).length;
200 var end = {line:last_line_num, ch:last_line_len}
200 var end = {line:last_line_num, ch:last_line_len}
201 var text = this.code_mirror.getRange(cursor, end);
201 var text = this.code_mirror.getRange(cursor, end);
202 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
202 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
203 return text;
203 return text;
204 };
204 };
205
205
206
206
207 /** Grow the cell by hand. This is used upon reloading from JSON, when the
207 /** Grow the cell by hand. This is used upon reloading from JSON, when the
208 * autogrow handler is not called.
208 * autogrow handler is not called.
209 *
209 *
210 * could be made static
210 * could be made static
211 *
211 *
212 * @param {Dom element} - element
212 * @param {Dom element} - element
213 * @method grow
213 * @method grow
214 **/
214 **/
215 Cell.prototype.grow = function(element) {
215 Cell.prototype.grow = function(element) {
216 var dom = element.get(0);
216 var dom = element.get(0);
217 var lines_count = 0;
217 var lines_count = 0;
218 // modified split rule from
218 // modified split rule from
219 // http://stackoverflow.com/questions/2035910/how-to-get-the-number-of-lines-in-a-textarea/2036424#2036424
219 // http://stackoverflow.com/questions/2035910/how-to-get-the-number-of-lines-in-a-textarea/2036424#2036424
220 var lines = dom.value.split(/\r|\r\n|\n/);
220 var lines = dom.value.split(/\r|\r\n|\n/);
221 lines_count = lines.length;
221 lines_count = lines.length;
222 if (lines_count >= 1) {
222 if (lines_count >= 1) {
223 dom.rows = lines_count;
223 dom.rows = lines_count;
224 } else {
224 } else {
225 dom.rows = 1;
225 dom.rows = 1;
226 }
226 }
227 };
227 };
228
228
229 /**
229 /**
230 * Show/Hide CodeMirror LineNumber
230 * Show/Hide CodeMirror LineNumber
231 * @method show_line_number
231 * @method show_line_numbers
232 *
232 *
233 * @param value {Bool} show (true), or hide (false) the line number in CodeMirror
233 * @param value {Bool} show (true), or hide (false) the line number in CodeMirror
234 **/
234 **/
235 Cell.prototype.show_line_numbers = function (value) {
235 Cell.prototype.show_line_numbers = function (value) {
236 this.code_mirror.setOption('lineNumbers', value);
236 this.code_mirror.setOption('lineNumbers', value);
237 this.code_mirror.refresh();
237 this.code_mirror.refresh();
238 };
238 };
239
239
240 /**
240 /**
241 * Toggle CodeMirror LineNumber
241 * Toggle CodeMirror LineNumber
242 * @method toggle_line_numbers
242 * @method toggle_line_numbers
243 **/
243 **/
244 Cell.prototype.toggle_line_numbers = function () {
244 Cell.prototype.toggle_line_numbers = function () {
245 if (this.code_mirror.getOption('lineNumbers') == false) {
245 var val = this.code_mirror.getOption('lineNumbers');
246 this.code_mirror.setOption('lineNumbers', true);
246 this.show_line_numbers(!val);
247 } else {
248 this.code_mirror.setOption('lineNumbers', false);
249 }
250 this.code_mirror.refresh();
251 };
247 };
252
248
253 /**
249 /**
254 * force codemirror highlight mode
250 * force codemirror highlight mode
255 * @method force_highlight
251 * @method force_highlight
256 * @param {object} - CodeMirror mode
252 * @param {object} - CodeMirror mode
257 **/
253 **/
258 Cell.prototype.force_highlight = function(mode) {
254 Cell.prototype.force_highlight = function(mode) {
259 this.user_highlight = mode;
255 this.user_highlight = mode;
260 this.auto_highlight();
256 this.auto_highlight();
261 };
257 };
262
258
263 /**
259 /**
264 * Try to autodetect cell highlight mode, or use selected mode
260 * Try to autodetect cell highlight mode, or use selected mode
265 * @methods _auto_highlight
261 * @methods _auto_highlight
266 * @private
262 * @private
267 * @param {String|object|undefined} - CodeMirror mode | 'auto'
263 * @param {String|object|undefined} - CodeMirror mode | 'auto'
268 **/
264 **/
269 Cell.prototype._auto_highlight = function (modes) {
265 Cell.prototype._auto_highlight = function (modes) {
270 //Here we handle manually selected modes
266 //Here we handle manually selected modes
271 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
267 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
272 {
268 {
273 var mode = this.user_highlight;
269 var mode = this.user_highlight;
274 CodeMirror.autoLoadMode(this.code_mirror, mode);
270 CodeMirror.autoLoadMode(this.code_mirror, mode);
275 this.code_mirror.setOption('mode', mode);
271 this.code_mirror.setOption('mode', mode);
276 return;
272 return;
277 }
273 }
278 var first_line = this.code_mirror.getLine(0);
274 var first_line = this.code_mirror.getLine(0);
279 // loop on every pairs
275 // loop on every pairs
280 for( var mode in modes) {
276 for( var mode in modes) {
281 var regs = modes[mode]['reg'];
277 var regs = modes[mode]['reg'];
282 // only one key every time but regexp can't be keys...
278 // only one key every time but regexp can't be keys...
283 for(var reg in regs ) {
279 for(var reg in regs ) {
284 // here we handle non magic_modes
280 // here we handle non magic_modes
285 if(first_line.match(regs[reg]) != null) {
281 if(first_line.match(regs[reg]) != null) {
286 if (mode.search('magic_') != 0) {
282 if (mode.search('magic_') != 0) {
287 this.code_mirror.setOption('mode',mode);
283 this.code_mirror.setOption('mode',mode);
288 CodeMirror.autoLoadMode(this.code_mirror, mode);
284 CodeMirror.autoLoadMode(this.code_mirror, mode);
289 return;
285 return;
290 }
286 }
291 var open = modes[mode]['open']|| "%%";
287 var open = modes[mode]['open']|| "%%";
292 var close = modes[mode]['close']|| "%%end";
288 var close = modes[mode]['close']|| "%%end";
293 var mmode = mode;
289 var mmode = mode;
294 mode = mmode.substr(6);
290 mode = mmode.substr(6);
295 CodeMirror.autoLoadMode(this.code_mirror, mode);
291 CodeMirror.autoLoadMode(this.code_mirror, mode);
296 // create on the fly a mode that swhitch between
292 // create on the fly a mode that swhitch between
297 // plain/text and smth else otherwise `%%` is
293 // plain/text and smth else otherwise `%%` is
298 // source of some highlight issues.
294 // source of some highlight issues.
299 // we use patchedGetMode to circumvent a bug in CM
295 // we use patchedGetMode to circumvent a bug in CM
300 CodeMirror.defineMode(mmode , function(config) {
296 CodeMirror.defineMode(mmode , function(config) {
301 return CodeMirror.multiplexingMode(
297 return CodeMirror.multiplexingMode(
302 CodeMirror.patchedGetMode(config, 'text/plain'),
298 CodeMirror.patchedGetMode(config, 'text/plain'),
303 // always set someting on close
299 // always set someting on close
304 {open: open, close: close,
300 {open: open, close: close,
305 mode: CodeMirror.patchedGetMode(config, mode),
301 mode: CodeMirror.patchedGetMode(config, mode),
306 delimStyle: "delimit"
302 delimStyle: "delimit"
307 }
303 }
308 );
304 );
309 });
305 });
310 this.code_mirror.setOption('mode', mmode);
306 this.code_mirror.setOption('mode', mmode);
311 return;
307 return;
312 }
308 }
313 }
309 }
314 }
310 }
315 // fallback on default (python)
311 // fallback on default (python)
316 var default_mode = this.default_mode || 'text/plain';
312 var default_mode = this.default_mode || 'text/plain';
317 this.code_mirror.setOption('mode', default_mode);
313 this.code_mirror.setOption('mode', default_mode);
318 };
314 };
319
315
320 IPython.Cell = Cell;
316 IPython.Cell = Cell;
321
317
322 return IPython;
318 return IPython;
323
319
324 }(IPython));
320 }(IPython));
325
321
General Comments 0
You need to be logged in to leave comments. Login now