Skip to content

Commit 7978c0f

Browse files
CadiChrisaaronmyattgnestorJarrad WhitakerNelyus
authored
Add keyboard shortcuts to menu dropdowns (jupyter#5525)
* render keyboard shortcuts from KeyboardManager render keyboard shortcuts from KeyboardManager * float menu keybindings to the right * Clean up styling * Humanize keybindings for display * Add some missing menu item/action pairs * Move styles to stylesheet * remove click event add/removal in enable/disable_paste * change the CSS rule to avoid wrapping in the middle of the shortcut text (jupyter#2759) Co-authored-by: Aaron Myatt <[email protected]> Co-authored-by: Grant Nestor <[email protected]> Co-authored-by: Jarrad Whitaker <[email protected]> Co-authored-by: Pierre Monod-Broca <[email protected]>
1 parent a94d316 commit 7978c0f

File tree

3 files changed

+52
-21
lines changed

3 files changed

+52
-21
lines changed

notebook/static/notebook/js/menubar.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ define([
77
'base/js/dialog',
88
'base/js/utils',
99
'base/js/i18n',
10+
'notebook/js/quickhelp',
1011
'./celltoolbar',
1112
'./tour',
1213
'moment',
13-
], function($, IPython, dialog, utils, i18n, celltoolbar, tour, moment) {
14+
], function($, IPython, dialog, utils, i18n, quickhelp, celltoolbar, tour, moment) {
1415
"use strict";
1516

1617
var MenuBar = function (selector, options) {
@@ -24,6 +25,7 @@ define([
2425
* options: dictionary
2526
* Dictionary of keyword arguments.
2627
* notebook: Notebook instance
28+
* render keyboard shortcuts from KeyboardManager
2729
* contents: ContentManager instance
2830
* events: $(Events) instance
2931
* save_widget: SaveWidget instance
@@ -37,7 +39,8 @@ define([
3739
this.base_url = options.base_url || utils.get_body_data("baseUrl");
3840
this.selector = selector;
3941
this.notebook = options.notebook;
40-
this.actions = this.notebook.keyboard_manager.actions;
42+
this.keyboard_manager = this.notebook.keyboard_manager;
43+
this.actions = this.keyboard_manager.actions;
4144
this.contents = options.contents;
4245
this.events = options.events;
4346
this.save_widget = options.save_widget;
@@ -232,6 +235,9 @@ define([
232235
'#int_kernel': 'interrupt-kernel',
233236
'#cut_cell': 'cut-cell',
234237
'#copy_cell': 'copy-cell',
238+
'#paste_cell_above': 'paste-cell-above',
239+
'#paste_cell_below': 'paste-cell-below',
240+
'#paste_cell_replace': 'paste-cell-replace',
235241
'#delete_cell': 'delete-cell',
236242
'#undelete_cell': 'undo-cell-deletion',
237243
'#split_cell': 'split-cell-at-cursor',
@@ -263,6 +269,7 @@ define([
263269
'#copy_cell_attachments': 'copy-cell-attachments',
264270
'#paste_cell_attachments': 'paste-cell-attachments',
265271
'#insert_image': 'insert-image',
272+
'#keyboard_shortcuts' : 'show-keyboard-shortcuts',
266273
'#edit_keyboard_shortcuts' : 'edit-command-mode-keyboard-shortcuts',
267274
};
268275

@@ -276,9 +283,22 @@ define([
276283
}
277284
// Immediately-Invoked Function Expression cause JS.
278285
(function(that, id_act, idx){
279-
that.element.find(idx).click(function(event){
286+
var el = that.element.find(idx);
287+
el.click(function(event){
280288
that.actions.call(id_act, event);
281289
});
290+
291+
var keybinding = that.keyboard_manager.command_shortcuts.get_action_shortcut(id_act) || that.keyboard_manager.edit_shortcuts.get_action_shortcut(id_act);
292+
293+
if (keybinding) {
294+
var shortcut = quickhelp.humanize_sequence(keybinding);
295+
var link_element = el.children('a');
296+
var text = link_element.text();
297+
link_element.text('');
298+
link_element.addClass('menu-shortcut-container');
299+
link_element.append('<span class="action">' + text + '</span>');
300+
link_element.append('<span class="kb">' + shortcut + '</span>');
301+
}
282302
})(that, id_act, idx);
283303
}
284304

@@ -295,9 +315,6 @@ define([
295315
} else {
296316
this.element.find('#notebook_tour').addClass("disabled");
297317
}
298-
this.element.find('#keyboard_shortcuts').click(function () {
299-
that.quick_help.show_keyboard_shortcuts();
300-
});
301318

302319
this.update_restore_checkpoint(null);
303320

notebook/static/notebook/js/notebook.js

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,17 +1640,11 @@ define([
16401640
var that = this;
16411641
if (!this.paste_enabled) {
16421642
$('#paste_cell_replace').removeClass('disabled')
1643-
.on('click', function () {that.keyboard_manager.actions.call(
1644-
'jupyter-notebook:paste-cell-replace');});
1645-
$('#paste_cell_replace > a').attr('aria-disabled', 'false');
1643+
$('#paste_cell_replace > a').attr('aria-disabled', 'false');
16461644
$('#paste_cell_above').removeClass('disabled')
1647-
.on('click', function () {that.keyboard_manager.actions.call(
1648-
'jupyter-notebook:paste-cell-above');});
1649-
$('#paste_cell_above > a').attr('aria-disabled', 'false');
1645+
$('#paste_cell_above > a').attr('aria-disabled', 'false');
16501646
$('#paste_cell_below').removeClass('disabled')
1651-
.on('click', function () {that.keyboard_manager.actions.call(
1652-
'jupyter-notebook:paste-cell-below');});
1653-
$('#paste_cell_below > a').attr('aria-disabled', 'false');
1647+
$('#paste_cell_below > a').attr('aria-disabled', 'false');
16541648
this.paste_enabled = true;
16551649
}
16561650
};
@@ -1660,12 +1654,12 @@ define([
16601654
*/
16611655
Notebook.prototype.disable_paste = function () {
16621656
if (this.paste_enabled) {
1663-
$('#paste_cell_replace').addClass('disabled').off('click');
1664-
$('#paste_cell_replace > a').attr('aria-disabled', 'true');
1665-
$('#paste_cell_above').addClass('disabled').off('click');
1666-
$('#paste_cell_above > a').attr('aria-disabled', 'true');
1667-
$('#paste_cell_below').addClass('disabled').off('click');
1668-
$('#paste_cell_below > a').attr('aria-disabled', 'true');
1657+
$('#paste_cell_replace').addClass('disabled');
1658+
$('#paste_cell_replace > a').attr('aria-disabled', 'true');
1659+
$('#paste_cell_above').addClass('disabled');
1660+
$('#paste_cell_above > a').attr('aria-disabled', 'true');
1661+
$('#paste_cell_below').addClass('disabled');
1662+
$('#paste_cell_below > a').attr('aria-disabled', 'true');
16691663
this.paste_enabled = false;
16701664
}
16711665
};

notebook/static/notebook/less/menubar.less

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ i.menu-icon {
7171
.pull-left();
7272
}
7373

74+
ul.dropdown-menu li a.menu-shortcut-container {
75+
display: flex;
76+
flex-direction: row;
77+
justify-content: space-between;
78+
align-items: flex-end;
79+
}
80+
7481
ul#help_menu li a{
7582
overflow: hidden;
7683
padding-right: 2.2em;
@@ -146,4 +153,17 @@ ul#help_menu li a{
146153
margin-left: 10px;
147154
}
148155

156+
.action {
157+
158+
}
159+
160+
.kb {
161+
color: darkgray;
162+
margin-left: 10px;
163+
text-transform: capitalize;
164+
kbd {
165+
white-space: nowrap;
166+
}
167+
}
168+
149169
//end submenu

0 commit comments

Comments
 (0)