##// END OF EJS Templates
Adding new logic to cells.
Brian E. Granger -
Show More
@@ -39,7 +39,8 b' var IPython = (function (IPython) {'
39 39 this.placeholder = options.placeholder || '';
40 40 this.read_only = options.cm_config.readOnly;
41 41 this.selected = false;
42 this.focused = false;
42 this.rendered = false;
43 this.mode = 'command';
43 44 this.metadata = {};
44 45 // load this from metadata later ?
45 46 this.user_highlight = 'auto';
@@ -130,49 +131,126 b' var IPython = (function (IPython) {'
130 131 * @method typeset
131 132 */
132 133 Cell.prototype.typeset = function () {
133 if (window.MathJax){
134 if (window.MathJax) {
134 135 var cell_math = this.element.get(0);
135 136 MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]);
136 }
137 };
137 138 };
138 139
139 140 /**
140 141 * handle cell level logic when a cell is selected
141 142 * @method select
143 * @return is the action being taken
142 144 */
143 145 Cell.prototype.select = function () {
144 this.element.addClass('selected');
145 this.selected = true;
146 if (!this.selected) {
147 this.element.addClass('selected');
148 this.element.removeClass('unselected');
149 this.selected = true;
150 return true;
151 } else {
152 return false;
153 };
146 154 };
147 155
148 156 /**
149 157 * handle cell level logic when a cell is unselected
150 158 * @method unselect
159 * @return is the action being taken
151 160 */
152 161 Cell.prototype.unselect = function () {
153 this.element.removeClass('selected');
154 this.selected = false;
162 if (this.selected) {
163 this.element.addClass('unselected');
164 this.element.removeClass('selected');
165 this.selected = false;
166 return true;
167 } else {
168 return false;
169 };
155 170 };
156 171
157 172 /**
158 * handle cell level logic when a cell is focused
159 * @method focus
173 * handle cell level logic when a cell is rendered
174 * @method render
175 * @return is the action being taken
160 176 */
161 Cell.prototype.focus = function () {
162 this.element.addClass('focused');
163 this.focused = true;
177 Cell.prototype.render = function () {
178 if (!this.rendered) {
179 this.element.addClass('rendered');
180 this.element.removeClass('unrendered');
181 this.rendered = true;
182 return true;
183 } else {
184 return false;
185 };
164 186 };
165 187
166 188 /**
167 * handle cell level logic when a cell is unfocused
168 * @method unfocus
189 * handle cell level logic when a cell is unrendered
190 * @method unrender
191 * @return is the action being taken
169 192 */
170 Cell.prototype.unfocus = function () {
171 this.element.removeClass('focused');
172 this.focused = false;
193 Cell.prototype.unrender = function () {
194 if (this.rendered) {
195 this.element.addClass('unrendered');
196 this.element.removeClass('rendered');
197 this.rendered = false;
198 return true;
199 } else {
200 return false;
201 };
173 202 };
174 203
175 204 /**
205 * enter the command mode for the cell
206 * @method command_mode
207 * @return is the action being taken
208 */
209 Cell.prototype.command_mode = function () {
210 if (this.mode !== 'command') {
211 this.element.addClass('command_mode');
212 this.element.removeClass('edit_mode');
213 this.mode = 'command';
214 return true;
215 } else {
216 return false;
217 };
218 };
219
220 /**
221 * enter the edit mode for the cell
222 * @method command_mode
223 * @return is the action being taken
224 */
225 Cell.prototype.edit_mode = function () {
226 if (this.mode !== 'edit') {
227 this.element.addClass('edit_mode');
228 this.element.removeClass('command_mode');
229 this.mode = 'edit';
230 return true;
231 } else {
232 return false;
233 };
234 }
235
236 /**
237 * Focus the cell in the DOM sense
238 * @method focus_cell
239 */
240 Cell.prototype.focus_cell = function () {
241 this.element.focus();
242 }
243
244 /**
245 * Focus the editor area so a user can type
246 * @method focus_editor
247 */
248 Cell.prototype.focus_editor = function () {
249 this.code_mirror.refresh();
250 this.code_mirror.focus();
251 }
252
253 /**
176 254 * should be overritten by subclass
177 255 * @method get_text
178 256 */
@@ -149,53 +149,60 b' var IPython = (function (IPython) {'
149 149 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
150 150
151 151 var that = this;
152 // whatever key is pressed, first, cancel the tooltip request before
153 // they are sent, and remove tooltip if any, except for tab again
154 if (event.type === 'keydown' && event.which != key.TAB ) {
155 IPython.tooltip.remove_and_cancel_tooltip();
156 }
157 152
158 var cur = editor.getCursor();
159 if (event.keyCode === key.ENTER){
160 this.auto_highlight();
161 }
153 if (this.mode === 'command') {
154 return false
155 } else if (this.mode === 'edit') {
156 // whatever key is pressed, first, cancel the tooltip request before
157 // they are sent, and remove tooltip if any, except for tab again
158 if (event.type === 'keydown' && event.which != key.TAB ) {
159 IPython.tooltip.remove_and_cancel_tooltip();
160 };
161
162 var cur = editor.getCursor();
163 if (event.keyCode === key.ENTER){
164 this.auto_highlight();
165 }
162 166
163 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
164 // Always ignore shift-enter in CodeMirror as we handle it.
165 return true;
166 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
167 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
168 // browser and keyboard layout !
169 // Pressing '(' , request tooltip, don't forget to reappend it
170 // The second argument says to hide the tooltip if the docstring
171 // is actually empty
172 IPython.tooltip.pending(that, true);
173 } else if (event.which === key.UPARROW && event.type === 'keydown') {
174 // If we are not at the top, let CM handle the up arrow and
175 // prevent the global keydown handler from handling it.
176 if (!that.at_top()) {
177 event.stop();
178 return false;
179 } else {
167 if (event.keyCode === key.ENTER && (event.shiftKey || event.ctrlKey)) {
168 // Always ignore shift-enter in CodeMirror as we handle it.
180 169 return true;
181 }
182 } else if (event.which === key.ESC) {
183 return IPython.tooltip.remove_and_cancel_tooltip(true);
184 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
185 // If we are not at the bottom, let CM handle the down arrow and
186 // prevent the global keydown handler from handling it.
187 if (!that.at_bottom()) {
188 event.stop();
189 return false;
190 } else {
170
171 } else if (event.which === 40 && event.type === 'keypress' && IPython.tooltip.time_before_tooltip >= 0) {
172 // triger on keypress (!) otherwise inconsistent event.which depending on plateform
173 // browser and keyboard layout !
174 // Pressing '(' , request tooltip, don't forget to reappend it
175 // The second argument says to hide the tooltip if the docstring
176 // is actually empty
177 IPython.tooltip.pending(that, true);
178 } else if (event.which === key.UPARROW && event.type === 'keydown') {
179 // If we are not at the top, let CM handle the up arrow and
180 // prevent the global keydown handler from handling it.
181 if (!that.at_top()) {
182 event.stop();
183 return false;
184 } else {
185 return true;
186 };
187 } else if (event.which === key.ESC) {
188 IPython.tooltip.remove_and_cancel_tooltip(true);
191 189 return true;
192 }
193 } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
194 if (editor.somethingSelected()){
195 var anchor = editor.getCursor("anchor");
196 var head = editor.getCursor("head");
197 if( anchor.line != head.line){
198 return false;
190 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
191 // If we are not at the bottom, let CM handle the down arrow and
192 // prevent the global keydown handler from handling it.
193 if (!that.at_bottom()) {
194 event.stop();
195 return false;
196 } else {
197 return true;
198 };
199 } else if (event.keyCode === key.TAB && event.type == 'keydown' && event.shiftKey) {
200 if (editor.somethingSelected()){
201 var anchor = editor.getCursor("anchor");
202 var head = editor.getCursor("head");
203 if( anchor.line != head.line){
204 return false;
205 }
199 206 }
200 207 }
201 208 IPython.tooltip.request(that);
@@ -213,13 +220,10 b' var IPython = (function (IPython) {'
213 220 // is empty. In this case, let CodeMirror handle indentation.
214 221 return false;
215 222 } else {
216 event.stop();
217 this.completer.startCompletion();
218 return true;
219 }
220 } else {
221 // keypress/keyup also trigger on TAB press, and we don't want to
222 // use those to disable tab completion.
223 // keypress/keyup also trigger on TAB press, and we don't want to
224 // use those to disable tab completion.
225 return false;
226 };
223 227 return false;
224 228 }
225 229 return false;
@@ -304,21 +308,46 b' var IPython = (function (IPython) {'
304 308 // Basic cell manipulation.
305 309
306 310 CodeCell.prototype.select = function () {
307 IPython.Cell.prototype.select.apply(this);
308 this.code_mirror.refresh();
309 this.auto_highlight();
311 var continue = IPython.Cell.prototype.select.apply(this);
312 if (continue) {
313 this.code_mirror.refresh();
314 this.auto_highlight();
315 };
316 return continue;
310 317 };
311 318
312 CodeCell.prototype.focus = function () {
313 IPython.Cell.prototype.focus.apply(this);
314 this.code_mirror.focus();
319 CodeCell.prototype.render = function () {
320 var continue = IPython.Cell.prototype.render.apply(this);
321 if (continue) {
322 this.execute();
323 };
324 return continue;
315 325 };
316 326
317 CodeCell.prototype.unfocus = function () {
318 IPython.Cell.prototype.focus.apply(this);
319 this.code_mirror.blur();
327 CodeCell.prototype.unrender = function () {
328 var continue = IPython.Cell.prototype.unrender.apply(this);
329 if (continue) {
330 this.clear_output(true, true, true);
331 };
332 return continue;
320 333 };
321 334
335 CodeCell.prototype.command_mode = function () {
336 var continue = IPython.Cell.prototype.command_mode.apply(this);
337 if (continue) {
338 this.focus_cell();
339 };
340 return continue;
341 }
342
343 CodeCell.prototype.edit_mode = function () {
344 var continue = IPython.Cell.prototype.edit_mode.apply(this);
345 if (continue) {
346 this.focus_editor();
347 };
348 return continue;
349 }
350
322 351 CodeCell.prototype.select_all = function () {
323 352 var start = {line: 0, ch: 0};
324 353 var nlines = this.code_mirror.lineCount();
@@ -946,7 +946,7 b' var IPython = (function (IPython) {'
946 946 text = '';
947 947 };
948 948 // The edit must come before the set_text.
949 target_cell.edit();
949 target_cell.unrender();
950 950 target_cell.set_text(text);
951 951 // make this value the starting point, so that we can only undo
952 952 // to this state, instead of a blank cell
@@ -976,7 +976,7 b' var IPython = (function (IPython) {'
976 976 text = '';
977 977 };
978 978 // The edit must come before the set_text.
979 target_cell.edit();
979 target_cell.unrender();
980 980 target_cell.set_text(text);
981 981 // make this value the starting point, so that we can only undo
982 982 // to this state, instead of a blank cell
@@ -1011,7 +1011,7 b' var IPython = (function (IPython) {'
1011 1011 };
1012 1012 // The edit must come before the set_text.
1013 1013 target_cell.set_level(level);
1014 target_cell.edit();
1014 target_cell.unrender();
1015 1015 target_cell.set_text(text);
1016 1016 // make this value the starting point, so that we can only undo
1017 1017 // to this state, instead of a blank cell
@@ -1179,7 +1179,7 b' var IPython = (function (IPython) {'
1179 1179 cell.set_text(textb);
1180 1180 cell.render();
1181 1181 var new_cell = this.insert_cell_above('markdown');
1182 new_cell.edit(); // editor must be visible to call set_text
1182 new_cell.unrender(); // editor must be visible to call set_text
1183 1183 new_cell.set_text(texta);
1184 1184 new_cell.render();
1185 1185 this.select_next();
@@ -1208,7 +1208,7 b' var IPython = (function (IPython) {'
1208 1208 if (cell instanceof IPython.CodeCell) {
1209 1209 cell.set_text(upper_text+'\n'+text);
1210 1210 } else if (cell instanceof IPython.MarkdownCell) {
1211 cell.edit();
1211 cell.unrender();
1212 1212 cell.set_text(upper_text+'\n'+text);
1213 1213 cell.render();
1214 1214 };
@@ -1238,7 +1238,7 b' var IPython = (function (IPython) {'
1238 1238 if (cell instanceof IPython.CodeCell) {
1239 1239 cell.set_text(text+'\n'+lower_text);
1240 1240 } else if (cell instanceof IPython.MarkdownCell) {
1241 cell.edit();
1241 cell.unrender();
1242 1242 cell.set_text(text+'\n'+lower_text);
1243 1243 cell.render();
1244 1244 };
@@ -104,13 +104,13 b' var IPython = (function (IPython) {'
104 104 this.element.keydown(function (event) {
105 105 if (event.which === 13 && !event.shiftKey) {
106 106 if (that.rendered) {
107 that.edit();
107 that.unrender();
108 108 return false;
109 109 };
110 110 };
111 111 });
112 112 this.element.dblclick(function () {
113 that.edit();
113 that.unrender();
114 114 });
115 115 };
116 116
@@ -134,57 +134,59 b' var IPython = (function (IPython) {'
134 134 return false;
135 135 };
136 136
137 /**
138 * Select the current cell and trigger 'focus'
139 * @method select
140 */
137 // Cell level actions
138
141 139 TextCell.prototype.select = function () {
142 IPython.Cell.prototype.select.apply(this);
143 var output = this.element.find("div.text_cell_render");
144 output.trigger('focus');
140 var continue = IPython.Cell.prototype.select.apply(this);
141 if (continue) {
142 if (this.mode === 'edit') {
143 this.code_mirror.refresh();
144 }
145 };
146 return continue;
145 147 };
146 148
147 /**
148 * unselect the current cell and `render` it
149 * @method unselect
150 */
151 TextCell.prototype.unselect = function() {
152 // render on selection of another cell
153 this.render();
154 IPython.Cell.prototype.unselect.apply(this);
149 TextCell.prototype.render = function () {
150 var continue = IPython.Cell.prototype.render.apply(this);
151 if (continue) {
152 this.execute();
153 };
154 return continue;
155 155 };
156 156
157 /**
158 *
159 * put the current cell in edition mode
160 * @method edit
161 */
162 TextCell.prototype.edit = function () {
163 if (this.rendered === true) {
157 TextCell.prototype.unrender = function () {
158 if (this.read_only) return;
159 var continue = IPython.Cell.prototype.unrender.apply(this);
160 if (continue) {
164 161 var text_cell = this.element;
165 162 var output = text_cell.find("div.text_cell_render");
166 163 output.hide();
167 164 text_cell.find('div.text_cell_input').show();
168 this.code_mirror.refresh();
169 this.code_mirror.focus();
170 // We used to need an additional refresh() after the focus, but
171 // it appears that this has been fixed in CM. This bug would show
172 // up on FF when a newly loaded markdown cell was edited.
173 this.rendered = false;
165 this.focus_editor();
174 166 if (this.get_text() === this.placeholder) {
175 167 this.set_text('');
176 168 this.refresh();
177 169 }
178 }
179 };
180 170
171 };
172 return continue;
173 };
181 174
182 /**
183 * Empty, Subclasses must define render.
184 * @method render
185 */
186 TextCell.prototype.render = function () {};
175 TextCell.prototype.command_mode = function () {
176 var continue = IPython.Cell.prototype.command_mode.apply(this);
177 if (continue) {
178 this.focus_cell();
179 };
180 return continue;
181 }
187 182
183 TextCell.prototype.edit_mode = function () {
184 var continue = IPython.Cell.prototype.edit_mode.apply(this);
185 if (continue) {
186 this.focus_editor();
187 };
188 return continue;
189 }
188 190
189 191 /**
190 192 * setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
@@ -382,11 +384,12 b' var IPython = (function (IPython) {'
382 384
383 385 /** @method render **/
384 386 RawCell.prototype.render = function () {
387
385 388 this.rendered = true;
386 389 var text = this.get_text();
387 390 if (text === "") { text = this.placeholder; }
388 console.log('rendering', text);
389 391 this.set_text(text);
392 this.unrender();
390 393 };
391 394
392 395
General Comments 0
You need to be logged in to leave comments. Login now