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