##// END OF EJS Templates
Update actions.js...
abalkin -
Show More
@@ -1,517 +1,518 b''
1 1 // Copyright (c) IPython Development Team.
2 2 // Distributed under the terms of the Modified BSD License.
3 3
4 4 define(function(require){
5 5 "use strict";
6 6
7 7 var ActionHandler = function (env) {
8 8 this.env = env || {};
9 9 Object.seal(this);
10 10 };
11 11
12 12 /**
13 13 * A bunch of predefined `Simple Actions` used by IPython.
14 14 * `Simple Actions` have the following keys:
15 15 * help (optional): a short string the describe the action.
16 16 * will be used in various context, like as menu name, tool tips on buttons,
17 17 * and short description in help menu.
18 18 * help_index (optional): a string used to sort action in help menu.
19 19 * icon (optional): a short string that represent the icon that have to be used with this
20 20 * action. this should mainly correspond to a Font_awesome class.
21 21 * handler : a function which is called when the action is activated. It will receive at first parameter
22 22 * a dictionary containing various handle to element of the notebook.
23 23 *
24 24 * action need to be registered with a **name** that can be use to refer to this action.
25 25 *
26 26 *
27 27 * if `help` is not provided it will be derived by replacing any dash by space
28 28 * in the **name** of the action. It is advised to provide a prefix to action name to
29 29 * avoid conflict the prefix should be all lowercase and end with a dot `.`
30 30 * in the absence of a prefix the behavior of the action is undefined.
31 31 *
32 32 * All action provided by IPython are prefixed with `ipython.`.
33 33 *
34 34 * One can register extra actions or replace an existing action with another one is possible
35 35 * but is considered undefined behavior.
36 36 *
37 37 **/
38 38 var _actions = {
39 39 'run-select-next': {
40 40 icon: 'fa-play',
41 41 help : 'run cell, select below',
42 42 help_index : 'ba',
43 43 handler : function (env) {
44 44 env.notebook.execute_cell_and_select_below();
45 45 }
46 46 },
47 47 'execute-in-place':{
48 48 help : 'run cell',
49 49 help_index : 'bb',
50 50 handler : function (env) {
51 51 env.notebook.execute_cell();
52 52 }
53 53 },
54 54 'execute-and-insert-after':{
55 55 help : 'run cell, insert below',
56 56 help_index : 'bc',
57 57 handler : function (env) {
58 58 env.notebook.execute_cell_and_insert_below();
59 59 }
60 60 },
61 61 'go-to-command-mode': {
62 62 help : 'command mode',
63 63 help_index : 'aa',
64 64 handler : function (env) {
65 65 env.notebook.command_mode();
66 66 }
67 67 },
68 68 'split-cell-at-cursor': {
69 69 help : 'split cell',
70 70 help_index : 'ea',
71 71 handler : function (env) {
72 72 env.notebook.split_cell();
73 73 }
74 74 },
75 75 'enter-edit-mode' : {
76 76 help_index : 'aa',
77 77 handler : function (env) {
78 78 env.notebook.edit_mode();
79 79 }
80 80 },
81 81 'select-previous-cell' : {
82 82 help_index : 'da',
83 83 handler : function (env) {
84 84 var index = env.notebook.get_selected_index();
85 85 if (index !== 0 && index !== null) {
86 86 env.notebook.select_prev();
87 87 env.notebook.focus_cell();
88 88 }
89 89 }
90 90 },
91 91 'select-next-cell' : {
92 92 help_index : 'db',
93 93 handler : function (env) {
94 94 var index = env.notebook.get_selected_index();
95 95 if (index !== (env.notebook.ncells()-1) && index !== null) {
96 96 env.notebook.select_next();
97 97 env.notebook.focus_cell();
98 98 }
99 99 }
100 100 },
101 101 'cut-selected-cell' : {
102 102 icon: 'fa-cut',
103 103 help_index : 'ee',
104 104 handler : function (env) {
105 105 var index = env.notebook.get_selected_index();
106 106 env.notebook.cut_cell();
107 107 env.notebook.select(index);
108 108 env.notebook.focus_cell();
109 109 }
110 110 },
111 111 'copy-selected-cell' : {
112 112 icon: 'fa-copy',
113 113 help_index : 'ef',
114 114 handler : function (env) {
115 115 env.notebook.copy_cell();
116 116 env.notebook.focus_cell();
117 117 }
118 118 },
119 119 'paste-cell-before' : {
120 120 help: 'paste cell above',
121 121 help_index : 'eg',
122 122 handler : function (env) {
123 123 env.notebook.paste_cell_above();
124 124 }
125 125 },
126 126 'paste-cell-after' : {
127 127 help: 'paste cell below',
128 128 icon: 'fa-paste',
129 129 help_index : 'eh',
130 130 handler : function (env) {
131 131 env.notebook.paste_cell_below();
132 132 }
133 133 },
134 134 'insert-cell-before' : {
135 135 help: 'insert cell above',
136 136 help_index : 'ec',
137 137 handler : function (env) {
138 138 env.notebook.insert_cell_above();
139 139 env.notebook.select_prev();
140 140 env.notebook.focus_cell();
141 141 }
142 142 },
143 143 'insert-cell-after' : {
144 144 help: 'insert cell below',
145 145 icon : 'fa-plus',
146 146 help_index : 'ed',
147 147 handler : function (env) {
148 148 env.notebook.insert_cell_below();
149 149 env.notebook.select_next();
150 150 env.notebook.focus_cell();
151 151 }
152 152 },
153 153 'change-selected-cell-to-code-cell' : {
154 154 help : 'to code',
155 155 help_index : 'ca',
156 156 handler : function (env) {
157 157 env.notebook.to_code();
158 158 }
159 159 },
160 160 'change-selected-cell-to-markdown-cell' : {
161 161 help : 'to markdown',
162 162 help_index : 'cb',
163 163 handler : function (env) {
164 164 env.notebook.to_markdown();
165 165 }
166 166 },
167 167 'change-selected-cell-to-raw-cell' : {
168 168 help : 'to raw',
169 169 help_index : 'cc',
170 170 handler : function (env) {
171 171 env.notebook.to_raw();
172 172 }
173 173 },
174 174 'change-selected-cell-to-heading-1' : {
175 175 help : 'to heading 1',
176 176 help_index : 'cd',
177 177 handler : function (env) {
178 178 env.notebook.to_heading(undefined, 1);
179 179 }
180 180 },
181 181 'change-selected-cell-to-heading-2' : {
182 182 help : 'to heading 2',
183 183 help_index : 'ce',
184 184 handler : function (env) {
185 185 env.notebook.to_heading(undefined, 2);
186 186 }
187 187 },
188 188 'change-selected-cell-to-heading-3' : {
189 189 help : 'to heading 3',
190 190 help_index : 'cf',
191 191 handler : function (env) {
192 192 env.notebook.to_heading(undefined, 3);
193 193 }
194 194 },
195 195 'change-selected-cell-to-heading-4' : {
196 196 help : 'to heading 4',
197 197 help_index : 'cg',
198 198 handler : function (env) {
199 199 env.notebook.to_heading(undefined, 4);
200 200 }
201 201 },
202 202 'change-selected-cell-to-heading-5' : {
203 203 help : 'to heading 5',
204 204 help_index : 'ch',
205 205 handler : function (env) {
206 206 env.notebook.to_heading(undefined, 5);
207 207 }
208 208 },
209 209 'change-selected-cell-to-heading-6' : {
210 210 help : 'to heading 6',
211 211 help_index : 'ci',
212 212 handler : function (env) {
213 213 env.notebook.to_heading(undefined, 6);
214 214 }
215 215 },
216 216 'toggle-output-visibility-selected-cell' : {
217 217 help : 'toggle output',
218 218 help_index : 'gb',
219 219 handler : function (env) {
220 220 env.notebook.toggle_output();
221 221 }
222 222 },
223 223 'toggle-output-scrolling-selected-cell' : {
224 224 help : 'toggle output scrolling',
225 225 help_index : 'gc',
226 226 handler : function (env) {
227 227 env.notebook.toggle_output_scroll();
228 228 }
229 229 },
230 230 'move-selected-cell-down' : {
231 231 icon: 'fa-arrow-down',
232 232 help_index : 'eb',
233 233 handler : function (env) {
234 234 env.notebook.move_cell_down();
235 235 }
236 236 },
237 237 'move-selected-cell-up' : {
238 238 icon: 'fa-arrow-up',
239 239 help_index : 'ea',
240 240 handler : function (env) {
241 241 env.notebook.move_cell_up();
242 242 }
243 243 },
244 244 'toggle-line-number-selected-cell' : {
245 245 help : 'toggle line numbers',
246 246 help_index : 'ga',
247 247 handler : function (env) {
248 248 env.notebook.cell_toggle_line_numbers();
249 249 }
250 250 },
251 251 'show-keyboard-shortcut-help-dialog' : {
252 252 help_index : 'ge',
253 253 handler : function (env) {
254 254 env.quick_help.show_keyboard_shortcuts();
255 255 }
256 256 },
257 257 'delete-cell': {
258 help: 'delete selected cell',
258 259 help_index : 'ej',
259 260 handler : function (env) {
260 261 env.notebook.delete_cell();
261 262 }
262 263 },
263 264 'interrupt-kernel':{
264 265 icon: 'fa-stop',
265 266 help_index : 'ha',
266 267 handler : function (env) {
267 268 env.notebook.kernel.interrupt();
268 269 env.notebook.focus_cell();
269 270 }
270 271 },
271 272 'restart-kernel':{
272 273 icon: 'fa-repeat',
273 274 help_index : 'hb',
274 275 handler : function (env) {
275 276 env.notebook.restart_kernel();
276 277 env.notebook.focus_cell();
277 278 }
278 279 },
279 280 'undo-last-cell-deletion' : {
280 281 help_index : 'ei',
281 282 handler : function (env) {
282 283 env.notebook.undelete_cell();
283 284 }
284 285 },
285 286 'merge-selected-cell-with-cell-after' : {
286 287 help : 'merge cell below',
287 288 help_index : 'ek',
288 289 handler : function (env) {
289 290 env.notebook.merge_cell_below();
290 291 }
291 292 },
292 293 'close-pager' : {
293 294 help_index : 'gd',
294 295 handler : function (env) {
295 296 env.pager.collapse();
296 297 }
297 298 }
298 299
299 300 };
300 301
301 302 /**
302 303 * A bunch of `Advance actions` for IPython.
303 304 * Cf `Simple Action` plus the following properties.
304 305 *
305 306 * handler: first argument of the handler is the event that triggerd the action
306 307 * (typically keypress). The handler is responsible for any modification of the
307 308 * event and event propagation.
308 309 * Is also responsible for returning false if the event have to be further ignored,
309 310 * true, to tell keyboard manager that it ignored the event.
310 311 *
311 312 * the second parameter of the handler is the environemnt passed to Simple Actions
312 313 *
313 314 **/
314 315 var custom_ignore = {
315 316 'ignore':{
316 317 handler : function () {
317 318 return true;
318 319 }
319 320 },
320 321 'move-cursor-up-or-previous-cell':{
321 322 handler : function (env, event) {
322 323 var index = env.notebook.get_selected_index();
323 324 var cell = env.notebook.get_cell(index);
324 325 var cm = env.notebook.get_selected_cell().code_mirror;
325 326 var cur = cm.getCursor();
326 327 if (cell && cell.at_top() && index !== 0 && cur.ch === 0) {
327 328 if(event){
328 329 event.preventDefault();
329 330 }
330 331 env.notebook.command_mode();
331 332 env.notebook.select_prev();
332 333 env.notebook.edit_mode();
333 334 cm = env.notebook.get_selected_cell().code_mirror;
334 335 cm.setCursor(cm.lastLine(), 0);
335 336 }
336 337 return false;
337 338 }
338 339 },
339 340 'move-cursor-down-or-next-cell':{
340 341 handler : function (env, event) {
341 342 var index = env.notebook.get_selected_index();
342 343 var cell = env.notebook.get_cell(index);
343 344 if (cell.at_bottom() && index !== (env.notebook.ncells()-1)) {
344 345 if(event){
345 346 event.preventDefault();
346 347 }
347 348 env.notebook.command_mode();
348 349 env.notebook.select_next();
349 350 env.notebook.edit_mode();
350 351 var cm = env.notebook.get_selected_cell().code_mirror;
351 352 cm.setCursor(0, 0);
352 353 }
353 354 return false;
354 355 }
355 356 },
356 357 'scroll-down': {
357 358 handler: function(env, event) {
358 359 if(event){
359 360 event.preventDefault();
360 361 }
361 362 return env.notebook.scroll_manager.scroll(1);
362 363 },
363 364 },
364 365 'scroll-up': {
365 366 handler: function(env, event) {
366 367 if(event){
367 368 event.preventDefault();
368 369 }
369 370 return env.notebook.scroll_manager.scroll(-1);
370 371 },
371 372 },
372 373 'save-notebook':{
373 374 help: "Save and Checkpoint",
374 375 help_index : 'fb',
375 376 icon: 'fa-save',
376 377 handler : function (env, event) {
377 378 env.notebook.save_checkpoint();
378 379 if(event){
379 380 event.preventDefault();
380 381 }
381 382 return false;
382 383 }
383 384 },
384 385 };
385 386
386 387 // private stuff that prepend `.ipython` to actions names
387 388 // and uniformize/fill in missing pieces in of an action.
388 389 var _prepare_handler = function(registry, subkey, source){
389 390 registry['ipython.'+subkey] = {};
390 391 registry['ipython.'+subkey].help = source[subkey].help||subkey.replace(/-/g,' ');
391 392 registry['ipython.'+subkey].help_index = source[subkey].help_index;
392 393 registry['ipython.'+subkey].icon = source[subkey].icon;
393 394 return source[subkey].handler;
394 395 };
395 396
396 397 // Will actually generate/register all the IPython actions
397 398 var fun = function(){
398 399 var final_actions = {};
399 400 var k;
400 401 for(k in _actions){
401 402 if(_actions.hasOwnProperty(k)){
402 403 // Js closure are function level not block level need to wrap in a IIFE
403 404 // and append ipython to event name these things do intercept event so are wrapped
404 405 // in a function that return false.
405 406 var handler = _prepare_handler(final_actions, k, _actions);
406 407 (function(key, handler){
407 408 final_actions['ipython.'+key].handler = function(env, event){
408 409 handler(env);
409 410 if(event){
410 411 event.preventDefault();
411 412 }
412 413 return false;
413 414 };
414 415 })(k, handler);
415 416 }
416 417 }
417 418
418 419 for(k in custom_ignore){
419 420 // Js closure are function level not block level need to wrap in a IIFE
420 421 // same as above, but decide for themselves wether or not they intercept events.
421 422 if(custom_ignore.hasOwnProperty(k)){
422 423 var handler = _prepare_handler(final_actions, k, custom_ignore);
423 424 (function(key, handler){
424 425 final_actions['ipython.'+key].handler = function(env, event){
425 426 return handler(env, event);
426 427 };
427 428 })(k, handler);
428 429 }
429 430 }
430 431
431 432 return final_actions;
432 433 };
433 434 ActionHandler.prototype._actions = fun();
434 435
435 436
436 437 /**
437 438 * extend the environment variable that will be pass to handlers
438 439 **/
439 440 ActionHandler.prototype.extend_env = function(env){
440 441 for(var k in env){
441 442 this.env[k] = env[k];
442 443 }
443 444 };
444 445
445 446 ActionHandler.prototype.register = function(action, name, prefix){
446 447 /**
447 448 * Register an `action` with an optional name and prefix.
448 449 *
449 450 * if name and prefix are not given they will be determined automatically.
450 451 * if action if just a `function` it will be wrapped in an anonymous action.
451 452 *
452 453 * @return the full name to access this action .
453 454 **/
454 455 action = this.normalise(action);
455 456 if( !name ){
456 457 name = 'autogenerated-'+String(action.handler);
457 458 }
458 459 prefix = prefix || 'auto';
459 460 var full_name = prefix+'.'+name;
460 461 this._actions[full_name] = action;
461 462 return full_name;
462 463
463 464 };
464 465
465 466
466 467 ActionHandler.prototype.normalise = function(data){
467 468 /**
468 469 * given an `action` or `function`, return a normalised `action`
469 470 * by setting all known attributes and removing unknown attributes;
470 471 **/
471 472 if(typeof(data) === 'function'){
472 473 data = {handler:data};
473 474 }
474 475 if(typeof(data.handler) !== 'function'){
475 476 throw('unknown datatype, cannot register');
476 477 }
477 478 var _data = data;
478 479 data = {};
479 480 data.handler = _data.handler;
480 481 data.help = _data.help || '';
481 482 data.icon = _data.icon || '';
482 483 data.help_index = _data.help_index || '';
483 484 return data;
484 485 };
485 486
486 487 ActionHandler.prototype.get_name = function(name_or_data){
487 488 /**
488 489 * given an `action` or `name` of a action, return the name attached to this action.
489 490 * if given the name of and corresponding actions does not exist in registry, return `null`.
490 491 **/
491 492
492 493 if(typeof(name_or_data) === 'string'){
493 494 if(this.exists(name_or_data)){
494 495 return name_or_data;
495 496 } else {
496 497 return null;
497 498 }
498 499 } else {
499 500 return this.register(name_or_data);
500 501 }
501 502 };
502 503
503 504 ActionHandler.prototype.get = function(name){
504 505 return this._actions[name];
505 506 };
506 507
507 508 ActionHandler.prototype.call = function(name, event, env){
508 509 return this._actions[name].handler(env|| this.env, event);
509 510 };
510 511
511 512 ActionHandler.prototype.exists = function(name){
512 513 return (typeof(this._actions[name]) !== 'undefined');
513 514 };
514 515
515 516 return {init:ActionHandler};
516 517
517 518 });
General Comments 0
You need to be logged in to leave comments. Login now