diff --git a/IPython/html/static/notebook/js/keyboardmanager.js b/IPython/html/static/notebook/js/keyboardmanager.js
index bf35e0f..c5d213e 100644
--- a/IPython/html/static/notebook/js/keyboardmanager.js
+++ b/IPython/html/static/notebook/js/keyboardmanager.js
@@ -1,14 +1,17 @@
-// Copyright (c) IPython Development Team.
-// Distributed under the terms of the Modified BSD License.
+//----------------------------------------------------------------------------
+// Copyright (C) 2011 The IPython Development Team
+//
+// Distributed under the terms of the BSD License. The full license is in
+// the file COPYING, distributed as part of this software.
+//----------------------------------------------------------------------------
-define([
- 'base/js/namespace',
- 'jquery',
- 'base/js/utils',
- 'base/js/keyboard',
-], function(IPython, $, utils, keyboard) {
+//============================================================================
+// Keyboard management
+//============================================================================
+
+var IPython = (function (IPython) {
"use strict";
-
+
var browser = utils.browser[0];
var platform = utils.platform;
@@ -40,437 +43,449 @@ define([
KeyboardManager.prototype.get_default_common_shortcuts = function() {
var that = this;
var shortcuts = {
- 'shift' : {
- help : '',
- help_index : '',
- handler : function (event) {
- // ignore shift keydown
- return true;
- }
- },
- 'shift-enter' : {
- help : 'run cell, select below',
- help_index : 'ba',
- handler : function (event) {
+ 'shift' : {
+ help : '',
+ help_index : '',
+ handler : function (event) {
+ // ignore shift keydown
+ return true;
+ }
+ },
+ 'shift-enter' : {
+ help : 'run cell, select below',
+ help_index : 'ba',
+ handler : function (event) {
that.notebook.execute_cell_and_select_below();
- return false;
- }
- },
- 'ctrl-enter' : {
- help : 'run cell',
- help_index : 'bb',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'ctrl-enter' : {
+ help : 'run cell',
+ help_index : 'bb',
+ handler : function (event) {
that.notebook.execute_cell();
- return false;
- }
- },
- 'alt-enter' : {
- help : 'run cell, insert below',
- help_index : 'bc',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'alt-enter' : {
+ help : 'run cell, insert below',
+ help_index : 'bc',
+ handler : function (event) {
that.notebook.execute_cell_and_insert_below();
- return false;
- }
+ return false;
}
- };
+ }
+ };
- if (platform === 'MacOS') {
+ if (platform === 'MacOS') {
shortcuts['cmd-s'] =
- {
- help : 'save notebook',
- help_index : 'fb',
- handler : function (event) {
+ {
+ help : 'save notebook',
+ help_index : 'fb',
+ handler : function (event) {
that.notebook.save_checkpoint();
- event.preventDefault();
- return false;
- }
- };
- } else {
+ event.preventDefault();
+ return false;
+ }
+ };
+ } else {
shortcuts['ctrl-s'] =
- {
- help : 'save notebook',
- help_index : 'fb',
- handler : function (event) {
+ {
+ help : 'save notebook',
+ help_index : 'fb',
+ handler : function (event) {
that.notebook.save_checkpoint();
- event.preventDefault();
- return false;
- }
- };
- }
+ event.preventDefault();
+ return false;
+ }
+ };
+ }
return shortcuts;
};
KeyboardManager.prototype.get_default_edit_shortcuts = function() {
var that = this;
return {
- 'esc' : {
- help : 'command mode',
- help_index : 'aa',
- handler : function (event) {
+ 'esc' : {
+ help : 'command mode',
+ help_index : 'aa',
+ handler : function (event) {
that.notebook.command_mode();
- return false;
- }
- },
- 'ctrl-m' : {
- help : 'command mode',
- help_index : 'ab',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'ctrl-m' : {
+ help : 'command mode',
+ help_index : 'ab',
+ handler : function (event) {
that.notebook.command_mode();
- return false;
- }
- },
- 'up' : {
- help : '',
- help_index : '',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'up' : {
+ help : '',
+ help_index : '',
+ handler : function (event) {
var index = that.notebook.get_selected_index();
var cell = that.notebook.get_cell(index);
- if (cell && cell.at_top() && index !== 0) {
- event.preventDefault();
+ if (cell && cell.at_top() && index !== 0) {
+ event.preventDefault();
that.notebook.command_mode();
that.notebook.select_prev();
that.notebook.edit_mode();
var cm = that.notebook.get_selected_cell().code_mirror;
- cm.setCursor(cm.lastLine(), 0);
- return false;
- } else if (cell) {
- var cm = cell.code_mirror;
- cm.execCommand('goLineUp');
- return false;
- }
+ cm.setCursor(cm.lastLine(), 0);
+ return false;
+ } else if (cell) {
+ var cm = cell.code_mirror;
+ cm.execCommand('goLineUp');
+ return false;
}
- },
- 'down' : {
- help : '',
- help_index : '',
- handler : function (event) {
+ }
+ },
+ 'down' : {
+ help : '',
+ help_index : '',
+ handler : function (event) {
var index = that.notebook.get_selected_index();
var cell = that.notebook.get_cell(index);
if (cell.at_bottom() && index !== (that.notebook.ncells()-1)) {
- event.preventDefault();
+ event.preventDefault();
that.notebook.command_mode();
that.notebook.select_next();
that.notebook.edit_mode();
var cm = that.notebook.get_selected_cell().code_mirror;
- cm.setCursor(0, 0);
- return false;
- } else {
- var cm = cell.code_mirror;
- cm.execCommand('goLineDown');
- return false;
- }
- }
- },
- 'ctrl-shift--' : {
- help : 'split cell',
- help_index : 'ea',
- handler : function (event) {
- that.notebook.split_cell();
+ cm.setCursor(0, 0);
return false;
- }
- },
- 'ctrl-shift-subtract' : {
- help : '',
- help_index : 'eb',
- handler : function (event) {
- that.notebook.split_cell();
+ } else {
+ var cm = cell.code_mirror;
+ cm.execCommand('goLineDown');
return false;
}
- },
- };
+ }
+ },
+ 'ctrl-shift--' : {
+ help : 'split cell',
+ help_index : 'ea',
+ handler : function (event) {
+ that.notebook.split_cell();
+ return false;
+ }
+ },
+ 'ctrl-shift-subtract' : {
+ help : '',
+ help_index : 'eb',
+ handler : function (event) {
+ that.notebook.split_cell();
+ return false;
+ }
+ },
+ };
};
KeyboardManager.prototype.get_default_command_shortcuts = function() {
var that = this;
return {
- 'enter' : {
- help : 'edit mode',
- help_index : 'aa',
- handler : function (event) {
+ 'space': {
+ help: "Scroll down to next H1 cell",
+ handler: function(event) {
+ return that.notebook.scrollmanager.scroll(1);
+ },
+ },
+ 'shift-space': {
+ help: "Scroll up to previous H1 cell",
+ handler: function(event) {
+ return that.notebook.scrollmanager.scroll(-1);
+ },
+ },
+ 'enter' : {
+ help : 'edit mode',
+ help_index : 'aa',
+ handler : function (event) {
that.notebook.edit_mode();
- return false;
- }
- },
- 'up' : {
- help : 'select previous cell',
- help_index : 'da',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'up' : {
+ help : 'select previous cell',
+ help_index : 'da',
+ handler : function (event) {
var index = that.notebook.get_selected_index();
- if (index !== 0 && index !== null) {
+ if (index !== 0 && index !== null) {
that.notebook.select_prev();
that.notebook.focus_cell();
- }
- return false;
}
- },
- 'down' : {
- help : 'select next cell',
- help_index : 'db',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'down' : {
+ help : 'select next cell',
+ help_index : 'db',
+ handler : function (event) {
var index = that.notebook.get_selected_index();
if (index !== (that.notebook.ncells()-1) && index !== null) {
that.notebook.select_next();
that.notebook.focus_cell();
- }
- return false;
}
- },
- 'k' : {
- help : 'select previous cell',
- help_index : 'dc',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'k' : {
+ help : 'select previous cell',
+ help_index : 'dc',
+ handler : function (event) {
var index = that.notebook.get_selected_index();
- if (index !== 0 && index !== null) {
+ if (index !== 0 && index !== null) {
that.notebook.select_prev();
that.notebook.focus_cell();
- }
- return false;
}
- },
- 'j' : {
- help : 'select next cell',
- help_index : 'dd',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'j' : {
+ help : 'select next cell',
+ help_index : 'dd',
+ handler : function (event) {
var index = that.notebook.get_selected_index();
if (index !== (that.notebook.ncells()-1) && index !== null) {
that.notebook.select_next();
that.notebook.focus_cell();
- }
- return false;
}
- },
- 'x' : {
- help : 'cut cell',
- help_index : 'ee',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'x' : {
+ help : 'cut cell',
+ help_index : 'ee',
+ handler : function (event) {
that.notebook.cut_cell();
- return false;
- }
- },
- 'c' : {
- help : 'copy cell',
- help_index : 'ef',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'c' : {
+ help : 'copy cell',
+ help_index : 'ef',
+ handler : function (event) {
that.notebook.copy_cell();
- return false;
- }
- },
- 'shift-v' : {
- help : 'paste cell above',
- help_index : 'eg',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'shift-v' : {
+ help : 'paste cell above',
+ help_index : 'eg',
+ handler : function (event) {
that.notebook.paste_cell_above();
- return false;
- }
- },
- 'v' : {
- help : 'paste cell below',
- help_index : 'eh',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'v' : {
+ help : 'paste cell below',
+ help_index : 'eh',
+ handler : function (event) {
that.notebook.paste_cell_below();
- return false;
- }
- },
- 'd' : {
- help : 'delete cell (press twice)',
- help_index : 'ej',
- count: 2,
- handler : function (event) {
+ return false;
+ }
+ },
+ 'd' : {
+ help : 'delete cell (press twice)',
+ help_index : 'ej',
+ count: 2,
+ handler : function (event) {
that.notebook.delete_cell();
- return false;
- }
- },
- 'a' : {
- help : 'insert cell above',
- help_index : 'ec',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'a' : {
+ help : 'insert cell above',
+ help_index : 'ec',
+ handler : function (event) {
that.notebook.insert_cell_above();
that.notebook.select_prev();
that.notebook.focus_cell();
- return false;
- }
- },
- 'b' : {
- help : 'insert cell below',
- help_index : 'ed',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'b' : {
+ help : 'insert cell below',
+ help_index : 'ed',
+ handler : function (event) {
that.notebook.insert_cell_below();
that.notebook.select_next();
that.notebook.focus_cell();
- return false;
- }
- },
- 'y' : {
- help : 'to code',
- help_index : 'ca',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'y' : {
+ help : 'to code',
+ help_index : 'ca',
+ handler : function (event) {
that.notebook.to_code();
- return false;
- }
- },
- 'm' : {
- help : 'to markdown',
- help_index : 'cb',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'm' : {
+ help : 'to markdown',
+ help_index : 'cb',
+ handler : function (event) {
that.notebook.to_markdown();
- return false;
- }
- },
- 'r' : {
- help : 'to raw',
- help_index : 'cc',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'r' : {
+ help : 'to raw',
+ help_index : 'cc',
+ handler : function (event) {
that.notebook.to_raw();
- return false;
- }
- },
- '1' : {
- help : 'to heading 1',
- help_index : 'cd',
- handler : function (event) {
+ return false;
+ }
+ },
+ '1' : {
+ help : 'to heading 1',
+ help_index : 'cd',
+ handler : function (event) {
that.notebook.to_heading(undefined, 1);
- return false;
- }
- },
- '2' : {
- help : 'to heading 2',
- help_index : 'ce',
- handler : function (event) {
+ return false;
+ }
+ },
+ '2' : {
+ help : 'to heading 2',
+ help_index : 'ce',
+ handler : function (event) {
that.notebook.to_heading(undefined, 2);
- return false;
- }
- },
- '3' : {
- help : 'to heading 3',
- help_index : 'cf',
- handler : function (event) {
+ return false;
+ }
+ },
+ '3' : {
+ help : 'to heading 3',
+ help_index : 'cf',
+ handler : function (event) {
that.notebook.to_heading(undefined, 3);
- return false;
- }
- },
- '4' : {
- help : 'to heading 4',
- help_index : 'cg',
- handler : function (event) {
+ return false;
+ }
+ },
+ '4' : {
+ help : 'to heading 4',
+ help_index : 'cg',
+ handler : function (event) {
that.notebook.to_heading(undefined, 4);
- return false;
- }
- },
- '5' : {
- help : 'to heading 5',
- help_index : 'ch',
- handler : function (event) {
+ return false;
+ }
+ },
+ '5' : {
+ help : 'to heading 5',
+ help_index : 'ch',
+ handler : function (event) {
that.notebook.to_heading(undefined, 5);
- return false;
- }
- },
- '6' : {
- help : 'to heading 6',
- help_index : 'ci',
- handler : function (event) {
+ return false;
+ }
+ },
+ '6' : {
+ help : 'to heading 6',
+ help_index : 'ci',
+ handler : function (event) {
that.notebook.to_heading(undefined, 6);
- return false;
- }
- },
- 'o' : {
- help : 'toggle output',
- help_index : 'gb',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'o' : {
+ help : 'toggle output',
+ help_index : 'gb',
+ handler : function (event) {
that.notebook.toggle_output();
- return false;
- }
- },
- 'shift-o' : {
- help : 'toggle output scrolling',
- help_index : 'gc',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'shift-o' : {
+ help : 'toggle output scrolling',
+ help_index : 'gc',
+ handler : function (event) {
that.notebook.toggle_output_scroll();
- return false;
- }
- },
- 's' : {
- help : 'save notebook',
- help_index : 'fa',
- handler : function (event) {
+ return false;
+ }
+ },
+ 's' : {
+ help : 'save notebook',
+ help_index : 'fa',
+ handler : function (event) {
that.notebook.save_checkpoint();
- return false;
- }
- },
- 'ctrl-j' : {
- help : 'move cell down',
- help_index : 'eb',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'ctrl-j' : {
+ help : 'move cell down',
+ help_index : 'eb',
+ handler : function (event) {
that.notebook.move_cell_down();
- return false;
- }
- },
- 'ctrl-k' : {
- help : 'move cell up',
- help_index : 'ea',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'ctrl-k' : {
+ help : 'move cell up',
+ help_index : 'ea',
+ handler : function (event) {
that.notebook.move_cell_up();
- return false;
- }
- },
- 'l' : {
- help : 'toggle line numbers',
- help_index : 'ga',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'l' : {
+ help : 'toggle line numbers',
+ help_index : 'ga',
+ handler : function (event) {
that.notebook.cell_toggle_line_numbers();
- return false;
- }
- },
- 'i' : {
- help : 'interrupt kernel (press twice)',
- help_index : 'ha',
- count: 2,
- handler : function (event) {
+ return false;
+ }
+ },
+ 'i' : {
+ help : 'interrupt kernel (press twice)',
+ help_index : 'ha',
+ count: 2,
+ handler : function (event) {
that.notebook.kernel.interrupt();
- return false;
- }
- },
- '0' : {
- help : 'restart kernel (press twice)',
- help_index : 'hb',
- count: 2,
- handler : function (event) {
+ return false;
+ }
+ },
+ '0' : {
+ help : 'restart kernel (press twice)',
+ help_index : 'hb',
+ count: 2,
+ handler : function (event) {
that.notebook.restart_kernel();
- return false;
- }
- },
- 'h' : {
- help : 'keyboard shortcuts',
- help_index : 'ge',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'h' : {
+ help : 'keyboard shortcuts',
+ help_index : 'ge',
+ handler : function (event) {
that.quick_help.show_keyboard_shortcuts();
- return false;
- }
- },
- 'z' : {
- help : 'undo last delete',
- help_index : 'ei',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'z' : {
+ help : 'undo last delete',
+ help_index : 'ei',
+ handler : function (event) {
that.notebook.undelete_cell();
- return false;
- }
- },
- 'shift-m' : {
- help : 'merge cell below',
- help_index : 'ek',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'shift-m' : {
+ help : 'merge cell below',
+ help_index : 'ek',
+ handler : function (event) {
that.notebook.merge_cell_below();
- return false;
- }
- },
- 'q' : {
- help : 'close pager',
- help_index : 'gd',
- handler : function (event) {
+ return false;
+ }
+ },
+ 'q' : {
+ help : 'close pager',
+ help_index : 'gd',
+ handler : function (event) {
that.pager.collapse();
- return false;
- }
- },
- };
+ return false;
+ }
+ },
+ };
};
KeyboardManager.prototype.bind_events = function () {
diff --git a/IPython/html/static/notebook/js/main.js b/IPython/html/static/notebook/js/main.js
index 4ddee4b..acfa4d5 100644
--- a/IPython/html/static/notebook/js/main.js
+++ b/IPython/html/static/notebook/js/main.js
@@ -19,6 +19,7 @@ require([
'notebook/js/keyboardmanager',
'notebook/js/config',
'notebook/js/kernelselector',
+ 'notebook/js/scrollmanager'
// only loaded, not used:
'custom/custom',
], function(
@@ -38,7 +39,8 @@ require([
savewidget,
keyboardmanager,
config,
- kernelselector
+ kernelselector,
+ scrollmanager
) {
"use strict";
@@ -67,6 +69,7 @@ require([
save_widget: save_widget,
config: user_config},
common_options));
+ var scrollmanager = new scrollmanager.ScrollManager(notebook);
var login_widget = new loginwidget.LoginWidget('span#login_widget', common_options);
var toolbar = new maintoolbar.MainToolBar('#maintoolbar-container', {
notebook: notebook,
@@ -132,6 +135,7 @@ require([
IPython.save_widget = save_widget;
IPython.config = user_config;
IPython.tooltip = notebook.tooltip;
+ IPython.scrollmanager = scrollmanager;
events.trigger('app_initialized.NotebookApp');
notebook.load_notebook(common_options.notebook_name, common_options.notebook_path);
diff --git a/IPython/html/static/notebook/js/scrollmanager.js b/IPython/html/static/notebook/js/scrollmanager.js
new file mode 100644
index 0000000..bd3465a
--- /dev/null
+++ b/IPython/html/static/notebook/js/scrollmanager.js
@@ -0,0 +1,78 @@
+// Copyright (c) IPython Development Team.
+// Distributed under the terms of the Modified BSD License.
+define([], function(){
+ "use strict";
+
+ var ScrollManager = function (notebook) {
+ // Public constructor.
+ this.notebook = notebook;
+ };
+
+ ScrollManager.prototype.scroll = function (delta) {
+ // Scroll the document.
+ //
+ // Parameters
+ // ----------
+ // delta: integer
+ // direction to scroll the document. Positive is downwards.
+
+ // If one or more slides exist, scroll to the slide.
+ var $slide_cells = $('.slideshow-slide');
+ if ($slide_cells.length > 0) {
+ var i, cell;
+
+ // Get the active slide cell index.
+ var selected_index = this.notebook.find_cell_index(this.notebook.get_selected_cell());
+ var active_slide = -1;
+ var cells = this.notebook.get_cells();
+ for (i = selected_index; i >= 0; i--) {
+ cell = cells[i];
+ var ns = cell.metadata.slideshow;
+ if (ns && ns.slide_type == 'slide') {
+ active_slide = i;
+ break;
+ }
+ }
+
+ // Translate cell index into slide cell index.
+ if (active_slide != -1) {
+ for (i = 0; i < $slide_cells.length; i++) {
+ if (cells[active_slide].element[0] == $slide_cells[i]) {
+ active_slide = i;
+ break;
+ }
+ }
+ }
+
+ // Scroll.
+ if (active_slide != -1 || delta > 0) {
+ active_slide += delta;
+ active_slide = Math.max(0, Math.min($slide_cells.length-1, active_slide));
+
+ var cell_element = $slide_cells[active_slide];
+ cell = $(cell_element).data('cell');
+ this.notebook.select(this.notebook.find_cell_index(cell));
+
+ this.scroll_to(cell_element);
+ //cell_element.scrollIntoView(true);
+ }
+
+ // Cancel browser keyboard scroll.
+ return false;
+
+ // No slides exist, default browser scroll
+ } else {
+ return true;
+ }
+ };
+
+ ScrollManager.prototype.scroll_to = function(destination) {
+ $('html, body').animate({'scrollTop': element.offset().top}, 'slow', 'swing');
+ };
+
+ // For convinience, add the ScrollManager class to the global namespace
+ IPython.ScrollManager = ScrollManager;
+ // Return naemspace for require.js loads
+ return ScrollManager;
+
+});