Commit da1e920d authored by Nathan Friend's avatar Nathan Friend Committed by Paul Slaughter

Update (almost) all shortcuts to use `keysFor`

This commit refactors almost all keyboard shortcuts to use keysFor.

A small number of shortcuts have been left as-is because their
implementation is unconventional/unusual. These will be addressed
in follow-up commits.
parent ac9e66c4
......@@ -6,13 +6,29 @@ import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import findAndFollowLink from '~/lib/utils/navigation_utility';
import { refreshCurrentPage, visitUrl } from '~/lib/utils/url_utility';
import { keysFor, TOGGLE_PERFORMANCE_BAR, TOGGLE_CANARY } from './keybindings';
import {
keysFor,
TOGGLE_KEYBOARD_SHORTCUTS_DIALOG,
START_SEARCH,
FOCUS_FILTER_BAR,
TOGGLE_PERFORMANCE_BAR,
TOGGLE_CANARY,
TOGGLE_MARKDOWN_PREVIEW,
GO_TO_YOUR_TODO_LIST,
GO_TO_ACTIVITY_FEED,
GO_TO_YOUR_ISSUES,
GO_TO_YOUR_MERGE_REQUESTS,
GO_TO_YOUR_PROJECTS,
GO_TO_YOUR_GROUPS,
GO_TO_MILESTONE_LIST,
GO_TO_YOUR_SNIPPETS,
GO_TO_PROJECT_FIND_FILE,
} from './keybindings';
import { disableShortcuts, shouldDisableShortcuts } from './shortcuts_toggle';
const defaultStopCallback = Mousetrap.prototype.stopCallback;
Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) {
if (['ctrl+shift+p', 'command+shift+p'].indexOf(combo) !== -1) {
if (keysFor(TOGGLE_MARKDOWN_PREVIEW).indexOf(combo) !== -1) {
return false;
}
......@@ -58,28 +74,41 @@ export default class Shortcuts {
this.helpModalElement = null;
this.helpModalVueInstance = null;
Mousetrap.bind('?', this.onToggleHelp);
Mousetrap.bind('s', Shortcuts.focusSearch);
Mousetrap.bind('/', Shortcuts.focusSearch);
Mousetrap.bind('f', this.focusFilter.bind(this));
Mousetrap.bind(keysFor(TOGGLE_KEYBOARD_SHORTCUTS_DIALOG), this.onToggleHelp);
Mousetrap.bind(keysFor(START_SEARCH), Shortcuts.focusSearch);
Mousetrap.bind(keysFor(FOCUS_FILTER_BAR), this.focusFilter.bind(this));
Mousetrap.bind(keysFor(TOGGLE_PERFORMANCE_BAR), Shortcuts.onTogglePerfBar);
Mousetrap.bind(keysFor(TOGGLE_CANARY), Shortcuts.onToggleCanary);
const findFileURL = document.body.dataset.findFile;
Mousetrap.bind('shift+t', () => findAndFollowLink('.shortcuts-todos'));
Mousetrap.bind('shift+a', () => findAndFollowLink('.dashboard-shortcuts-activity'));
Mousetrap.bind('shift+i', () => findAndFollowLink('.dashboard-shortcuts-issues'));
Mousetrap.bind('shift+m', () => findAndFollowLink('.dashboard-shortcuts-merge_requests'));
Mousetrap.bind('shift+p', () => findAndFollowLink('.dashboard-shortcuts-projects'));
Mousetrap.bind('shift+g', () => findAndFollowLink('.dashboard-shortcuts-groups'));
Mousetrap.bind('shift+l', () => findAndFollowLink('.dashboard-shortcuts-milestones'));
Mousetrap.bind('shift+s', () => findAndFollowLink('.dashboard-shortcuts-snippets'));
Mousetrap.bind(['ctrl+shift+p', 'command+shift+p'], Shortcuts.toggleMarkdownPreview);
Mousetrap.bind(keysFor(GO_TO_YOUR_TODO_LIST), () => findAndFollowLink('.shortcuts-todos'));
Mousetrap.bind(keysFor(GO_TO_ACTIVITY_FEED), () =>
findAndFollowLink('.dashboard-shortcuts-activity'),
);
Mousetrap.bind(keysFor(GO_TO_YOUR_ISSUES), () =>
findAndFollowLink('.dashboard-shortcuts-issues'),
);
Mousetrap.bind(keysFor(GO_TO_YOUR_MERGE_REQUESTS), () =>
findAndFollowLink('.dashboard-shortcuts-merge_requests'),
);
Mousetrap.bind(keysFor(GO_TO_YOUR_PROJECTS), () =>
findAndFollowLink('.dashboard-shortcuts-projects'),
);
Mousetrap.bind(keysFor(GO_TO_YOUR_GROUPS), () =>
findAndFollowLink('.dashboard-shortcuts-groups'),
);
Mousetrap.bind(keysFor(GO_TO_MILESTONE_LIST), () =>
findAndFollowLink('.dashboard-shortcuts-milestones'),
);
Mousetrap.bind(keysFor(GO_TO_YOUR_SNIPPETS), () =>
findAndFollowLink('.dashboard-shortcuts-snippets'),
);
Mousetrap.bind(keysFor(TOGGLE_MARKDOWN_PREVIEW), Shortcuts.toggleMarkdownPreview);
if (typeof findFileURL !== 'undefined' && findFileURL !== null) {
Mousetrap.bind('t', () => {
Mousetrap.bind(keysFor(GO_TO_PROJECT_FIND_FILE), () => {
visitUrl(findFileURL);
});
}
......
import Mousetrap from 'mousetrap';
import { keysFor, PROJECT_FILES_GO_TO_PERMALINK } from '~/behaviors/shortcuts/keybindings';
import {
getLocationHash,
updateHistory,
......@@ -28,7 +29,7 @@ export default class ShortcutsBlob extends Shortcuts {
this.shortcircuitPermalinkButton();
Mousetrap.bind('y', this.moveToFilePermalink.bind(this));
Mousetrap.bind(keysFor(PROJECT_FILES_GO_TO_PERMALINK), this.moveToFilePermalink.bind(this));
}
moveToFilePermalink() {
......
import Mousetrap from 'mousetrap';
import {
keysFor,
PROJECT_FILES_MOVE_SELECTION_UP,
PROJECT_FILES_MOVE_SELECTION_DOWN,
PROJECT_FILES_OPEN_SELECTION,
PROJECT_FILES_GO_BACK,
} from '~/behaviors/shortcuts/keybindings';
import ShortcutsNavigation from './shortcuts_navigation';
export default class ShortcutsFindFile extends ShortcutsNavigation {
......@@ -10,7 +17,10 @@ export default class ShortcutsFindFile extends ShortcutsNavigation {
Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) {
if (
element === projectFindFile.inputElement[0] &&
(combo === 'up' || combo === 'down' || combo === 'esc' || combo === 'enter')
(keysFor(PROJECT_FILES_MOVE_SELECTION_UP).includes(combo) ||
keysFor(PROJECT_FILES_MOVE_SELECTION_DOWN).includes(combo) ||
keysFor(PROJECT_FILES_GO_BACK).includes(combo) ||
keysFor(PROJECT_FILES_OPEN_SELECTION).includes(combo))
) {
// when press up/down key in textbox, cursor prevent to move to home/end
e.preventDefault();
......@@ -20,9 +30,9 @@ export default class ShortcutsFindFile extends ShortcutsNavigation {
return oldStopCallback.call(this, e, element, combo);
};
Mousetrap.bind('up', projectFindFile.selectRowUp);
Mousetrap.bind('down', projectFindFile.selectRowDown);
Mousetrap.bind('esc', projectFindFile.goToTree);
Mousetrap.bind('enter', projectFindFile.goToBlob);
Mousetrap.bind(keysFor(PROJECT_FILES_MOVE_SELECTION_UP), projectFindFile.selectRowUp);
Mousetrap.bind(keysFor(PROJECT_FILES_MOVE_SELECTION_DOWN), projectFindFile.selectRowDown);
Mousetrap.bind(keysFor(PROJECT_FILES_GO_BACK), projectFindFile.goToTree);
Mousetrap.bind(keysFor(PROJECT_FILES_OPEN_SELECTION), projectFindFile.goToBlob);
}
}
......@@ -5,18 +5,33 @@ import { getSelectedFragment } from '~/lib/utils/common_utils';
import { isElementVisible } from '~/lib/utils/dom_utils';
import Sidebar from '../../right_sidebar';
import { CopyAsGFM } from '../markdown/copy_as_gfm';
import {
keysFor,
ISSUE_MR_CHANGE_ASSIGNEE,
ISSUE_MR_CHANGE_MILESTONE,
ISSUABLE_CHANGE_LABEL,
ISSUABLE_COMMENT_OR_REPLY,
ISSUABLE_EDIT_DESCRIPTION,
MR_COPY_SOURCE_BRANCH_NAME,
} from './keybindings';
import Shortcuts from './shortcuts';
export default class ShortcutsIssuable extends Shortcuts {
constructor() {
super();
Mousetrap.bind('a', () => ShortcutsIssuable.openSidebarDropdown('assignee'));
Mousetrap.bind('m', () => ShortcutsIssuable.openSidebarDropdown('milestone'));
Mousetrap.bind('l', () => ShortcutsIssuable.openSidebarDropdown('labels'));
Mousetrap.bind('r', ShortcutsIssuable.replyWithSelectedText);
Mousetrap.bind('e', ShortcutsIssuable.editIssue);
Mousetrap.bind('b', ShortcutsIssuable.copyBranchName);
Mousetrap.bind(keysFor(ISSUE_MR_CHANGE_ASSIGNEE), () =>
ShortcutsIssuable.openSidebarDropdown('assignee'),
);
Mousetrap.bind(keysFor(ISSUE_MR_CHANGE_MILESTONE), () =>
ShortcutsIssuable.openSidebarDropdown('milestone'),
);
Mousetrap.bind(keysFor(ISSUABLE_CHANGE_LABEL), () =>
ShortcutsIssuable.openSidebarDropdown('labels'),
);
Mousetrap.bind(keysFor(ISSUABLE_COMMENT_OR_REPLY), ShortcutsIssuable.replyWithSelectedText);
Mousetrap.bind(keysFor(ISSUABLE_EDIT_DESCRIPTION), ShortcutsIssuable.editIssue);
Mousetrap.bind(keysFor(MR_COPY_SOURCE_BRANCH_NAME), ShortcutsIssuable.copyBranchName);
}
static replyWithSelectedText() {
......
import Mousetrap from 'mousetrap';
import findAndFollowLink from '../../lib/utils/navigation_utility';
import {
keysFor,
GO_TO_PROJECT_OVERVIEW,
GO_TO_PROJECT_ACTIVITY_FEED,
GO_TO_PROJECT_RELEASES,
GO_TO_PROJECT_FILES,
GO_TO_PROJECT_COMMITS,
GO_TO_PROJECT_JOBS,
GO_TO_PROJECT_REPO_GRAPH,
GO_TO_PROJECT_REPO_CHARTS,
GO_TO_PROJECT_ISSUES,
GO_TO_PROJECT_ISSUE_BOARDS,
GO_TO_PROJECT_MERGE_REQUESTS,
GO_TO_PROJECT_WIKI,
GO_TO_PROJECT_SNIPPETS,
GO_TO_PROJECT_KUBERNETES,
GO_TO_PROJECT_ENVIRONMENTS,
GO_TO_PROJECT_METRICS,
NEW_ISSUE,
} from './keybindings';
import Shortcuts from './shortcuts';
export default class ShortcutsNavigation extends Shortcuts {
constructor() {
super();
Mousetrap.bind('g p', () => findAndFollowLink('.shortcuts-project'));
Mousetrap.bind('g v', () => findAndFollowLink('.shortcuts-project-activity'));
Mousetrap.bind('g r', () => findAndFollowLink('.shortcuts-project-releases'));
Mousetrap.bind('g f', () => findAndFollowLink('.shortcuts-tree'));
Mousetrap.bind('g c', () => findAndFollowLink('.shortcuts-commits'));
Mousetrap.bind('g j', () => findAndFollowLink('.shortcuts-builds'));
Mousetrap.bind('g n', () => findAndFollowLink('.shortcuts-network'));
Mousetrap.bind('g d', () => findAndFollowLink('.shortcuts-repository-charts'));
Mousetrap.bind('g i', () => findAndFollowLink('.shortcuts-issues'));
Mousetrap.bind('g b', () => findAndFollowLink('.shortcuts-issue-boards'));
Mousetrap.bind('g m', () => findAndFollowLink('.shortcuts-merge_requests'));
Mousetrap.bind('g w', () => findAndFollowLink('.shortcuts-wiki'));
Mousetrap.bind('g s', () => findAndFollowLink('.shortcuts-snippets'));
Mousetrap.bind('g k', () => findAndFollowLink('.shortcuts-kubernetes'));
Mousetrap.bind('g e', () => findAndFollowLink('.shortcuts-environments'));
Mousetrap.bind('g l', () => findAndFollowLink('.shortcuts-metrics'));
Mousetrap.bind('i', () => findAndFollowLink('.shortcuts-new-issue'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_OVERVIEW), () => findAndFollowLink('.shortcuts-project'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_ACTIVITY_FEED), () =>
findAndFollowLink('.shortcuts-project-activity'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_RELEASES), () =>
findAndFollowLink('.shortcuts-project-releases'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_FILES), () => findAndFollowLink('.shortcuts-tree'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_COMMITS), () => findAndFollowLink('.shortcuts-commits'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_JOBS), () => findAndFollowLink('.shortcuts-builds'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_REPO_GRAPH), () =>
findAndFollowLink('.shortcuts-network'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_REPO_CHARTS), () =>
findAndFollowLink('.shortcuts-repository-charts'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_ISSUES), () => findAndFollowLink('.shortcuts-issues'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_ISSUE_BOARDS), () =>
findAndFollowLink('.shortcuts-issue-boards'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_MERGE_REQUESTS), () =>
findAndFollowLink('.shortcuts-merge_requests'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_WIKI), () => findAndFollowLink('.shortcuts-wiki'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_SNIPPETS), () => findAndFollowLink('.shortcuts-snippets'));
Mousetrap.bind(keysFor(GO_TO_PROJECT_KUBERNETES), () =>
findAndFollowLink('.shortcuts-kubernetes'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_ENVIRONMENTS), () =>
findAndFollowLink('.shortcuts-environments'),
);
Mousetrap.bind(keysFor(GO_TO_PROJECT_METRICS), () => findAndFollowLink('.shortcuts-metrics'));
Mousetrap.bind(keysFor(NEW_ISSUE), () => findAndFollowLink('.shortcuts-new-issue'));
}
}
import Mousetrap from 'mousetrap';
import {
keysFor,
REPO_GRAPH_SCROLL_BOTTOM,
REPO_GRAPH_SCROLL_DOWN,
REPO_GRAPH_SCROLL_LEFT,
REPO_GRAPH_SCROLL_RIGHT,
REPO_GRAPH_SCROLL_TOP,
REPO_GRAPH_SCROLL_UP,
} from './keybindings';
import ShortcutsNavigation from './shortcuts_navigation';
export default class ShortcutsNetwork extends ShortcutsNavigation {
constructor(graph) {
super();
Mousetrap.bind(['left', 'h'], graph.scrollLeft);
Mousetrap.bind(['right', 'l'], graph.scrollRight);
Mousetrap.bind(['up', 'k'], graph.scrollUp);
Mousetrap.bind(['down', 'j'], graph.scrollDown);
Mousetrap.bind(['shift+up', 'shift+k'], graph.scrollTop);
Mousetrap.bind(['shift+down', 'shift+j'], graph.scrollBottom);
Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_LEFT), graph.scrollLeft);
Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_RIGHT), graph.scrollRight);
Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_UP), graph.scrollUp);
Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_DOWN), graph.scrollDown);
Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_TOP), graph.scrollTop);
Mousetrap.bind(keysFor(REPO_GRAPH_SCROLL_BOTTOM), graph.scrollBottom);
}
}
import Mousetrap from 'mousetrap';
import findAndFollowLink from '../../lib/utils/navigation_utility';
import { keysFor, EDIT_WIKI_PAGE } from './keybindings';
import ShortcutsNavigation from './shortcuts_navigation';
export default class ShortcutsWiki extends ShortcutsNavigation {
constructor() {
super();
Mousetrap.bind('e', ShortcutsWiki.editWiki);
Mousetrap.bind(keysFor(EDIT_WIKI_PAGE), ShortcutsWiki.editWiki);
}
static editWiki() {
......
......@@ -2,6 +2,11 @@
/* global Mousetrap */
import 'mousetrap';
import { GlButton, GlButtonGroup, GlTooltipDirective } from '@gitlab/ui';
import {
keysFor,
ISSUE_PREVIOUS_DESIGN,
ISSUE_NEXT_DESIGN,
} from '~/behaviors/shortcuts/keybindings';
import { s__, sprintf } from '~/locale';
import allDesignsMixin from '../../mixins/all_designs';
import { DESIGN_ROUTE_NAME } from '../../router/constants';
......@@ -46,11 +51,14 @@ export default {
},
},
mounted() {
Mousetrap.bind('left', () => this.navigateToDesign(this.previousDesign));
Mousetrap.bind('right', () => this.navigateToDesign(this.nextDesign));
Mousetrap.bind(keysFor(ISSUE_PREVIOUS_DESIGN), () =>
this.navigateToDesign(this.previousDesign),
);
Mousetrap.bind(keysFor(ISSUE_NEXT_DESIGN), () => this.navigateToDesign(this.nextDesign));
},
beforeDestroy() {
Mousetrap.unbind(['left', 'right'], this.navigateToDesign);
Mousetrap.unbind(keysFor(ISSUE_PREVIOUS_DESIGN));
Mousetrap.unbind(keysFor(ISSUE_NEXT_DESIGN));
},
methods: {
navigateToDesign(design) {
......
......@@ -2,6 +2,7 @@
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import Mousetrap from 'mousetrap';
import { ApolloMutation } from 'vue-apollo';
import { keysFor, ISSUE_CLOSE_DESIGN } from '~/behaviors/shortcuts/keybindings';
import createFlash from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
......@@ -171,7 +172,7 @@ export default {
},
},
mounted() {
Mousetrap.bind('esc', this.closeDesign);
Mousetrap.bind(keysFor(ISSUE_CLOSE_DESIGN), this.closeDesign);
this.trackPageViewEvent();
// Set active discussion immediately.
......@@ -180,7 +181,7 @@ export default {
this.updateActiveDiscussionFromUrl();
},
beforeDestroy() {
Mousetrap.unbind('esc', this.closeDesign);
Mousetrap.unbind(keysFor(ISSUE_CLOSE_DESIGN));
},
methods: {
addImageDiffNoteToStore(store, { data: { createImageDiffNote } }) {
......
......@@ -3,6 +3,13 @@ import { GlLoadingIcon, GlPagination, GlSprintf } from '@gitlab/ui';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import Mousetrap from 'mousetrap';
import { mapState, mapGetters, mapActions } from 'vuex';
import {
keysFor,
MR_PREVIOUS_FILE_IN_DIFF,
MR_NEXT_FILE_IN_DIFF,
MR_COMMITS_NEXT_COMMIT,
MR_COMMITS_PREVIOUS_COMMIT,
} from '~/behaviors/shortcuts/keybindings';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import { isSingleViewStyle } from '~/helpers/diffs_helper';
import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils';
......@@ -406,30 +413,23 @@ export default {
}
},
setEventListeners() {
Mousetrap.bind(['[', 'k', ']', 'j'], (e, combo) => {
switch (combo) {
case '[':
case 'k':
this.jumpToFile(-1);
break;
case ']':
case 'j':
this.jumpToFile(+1);
break;
default:
break;
}
});
Mousetrap.bind(keysFor(MR_PREVIOUS_FILE_IN_DIFF), () => this.jumpToFile(-1));
Mousetrap.bind(keysFor(MR_NEXT_FILE_IN_DIFF), () => this.jumpToFile(+1));
if (this.commit) {
Mousetrap.bind('c', () => this.moveToNeighboringCommit({ direction: 'next' }));
Mousetrap.bind('x', () => this.moveToNeighboringCommit({ direction: 'previous' }));
Mousetrap.bind(keysFor(MR_COMMITS_NEXT_COMMIT), () =>
this.moveToNeighboringCommit({ direction: 'next' }),
);
Mousetrap.bind(keysFor(MR_COMMITS_PREVIOUS_COMMIT), () =>
this.moveToNeighboringCommit({ direction: 'previous' }),
);
}
},
removeEventListeners() {
Mousetrap.unbind(['[', 'k', ']', 'j']);
Mousetrap.unbind('c');
Mousetrap.unbind('x');
Mousetrap.unbind(keysFor(MR_PREVIOUS_FILE_IN_DIFF));
Mousetrap.unbind(keysFor(MR_NEXT_FILE_IN_DIFF));
Mousetrap.unbind(keysFor(MR_COMMITS_NEXT_COMMIT));
Mousetrap.unbind(keysFor(MR_COMMITS_PREVIOUS_COMMIT));
},
jumpToFile(step) {
const targetIndex = this.currentDiffIndex + step;
......
<script>
/* global Mousetrap */
import 'mousetrap';
import {
keysFor,
MR_NEXT_UNRESOLVED_DISCUSSION,
MR_PREVIOUS_UNRESOLVED_DISCUSSION,
} from '~/behaviors/shortcuts/keybindings';
import eventHub from '~/notes/event_hub';
import discussionNavigation from '~/notes/mixins/discussion_navigation';
......@@ -10,12 +15,12 @@ export default {
eventHub.$on('jumpToFirstUnresolvedDiscussion', this.jumpToFirstUnresolvedDiscussion);
},
mounted() {
Mousetrap.bind('n', this.jumpToNextDiscussion);
Mousetrap.bind('p', this.jumpToPreviousDiscussion);
Mousetrap.bind(keysFor(MR_NEXT_UNRESOLVED_DISCUSSION), this.jumpToNextDiscussion);
Mousetrap.bind(keysFor(MR_PREVIOUS_UNRESOLVED_DISCUSSION), this.jumpToPreviousDiscussion);
},
beforeDestroy() {
Mousetrap.unbind('n');
Mousetrap.unbind('p');
Mousetrap.unbind(keysFor(MR_NEXT_UNRESOLVED_DISCUSSION));
Mousetrap.unbind(keysFor(MR_PREVIOUS_UNRESOLVED_DISCUSSION));
eventHub.$off('jumpToFirstUnresolvedDiscussion', this.jumpToFirstUnresolvedDiscussion);
},
......
......@@ -3,6 +3,7 @@ import { GlIcon } from '@gitlab/ui';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import Mousetrap from 'mousetrap';
import VirtualList from 'vue-virtual-scroll-list';
import { keysFor, MR_GO_TO_FILE } from '~/behaviors/shortcuts/keybindings';
import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/utils/keycodes';
import Item from './item.vue';
......@@ -128,7 +129,7 @@ export default {
this.focusedIndex = 0;
}
Mousetrap.bind(['t', 'mod+p'], (e) => {
Mousetrap.bind(keysFor(MR_GO_TO_FILE), (e) => {
if (e.preventDefault) {
e.preventDefault();
}
......
<script>
import { GlPopover, GlButton, GlTooltipDirective, GlIcon } from '@gitlab/ui';
import $ from 'jquery';
import { keysFor, BOLD_TEXT, ITALIC_TEXT, LINK_TEXT } from '~/behaviors/shortcuts/keybindings';
import { getSelectedFragment } from '~/lib/utils/common_utils';
import { s__ } from '~/locale';
import { CopyAsGFM } from '../../../behaviors/markdown/copy_as_gfm';
......@@ -116,6 +117,11 @@ export default {
.catch(() => {});
},
},
shortcuts: {
bold: keysFor(BOLD_TEXT),
italic: keysFor(ITALIC_TEXT),
link: keysFor(LINK_TEXT),
},
};
</script>
......@@ -143,7 +149,7 @@ export default {
:button-title="
sprintf(s__('MarkdownEditor|Add bold text (%{modifierKey}B)'), { modifierKey })
"
shortcuts="mod+b"
:shortcuts="$options.shortcuts.bold"
icon="bold"
/>
<toolbar-button
......@@ -151,7 +157,7 @@ export default {
:button-title="
sprintf(s__('MarkdownEditor|Add italic text (%{modifierKey}I)'), { modifierKey })
"
shortcuts="mod+i"
:shortcuts="$options.shortcuts.italic"
icon="italic"
/>
<toolbar-button
......@@ -208,7 +214,7 @@ export default {
:button-title="
sprintf(s__('MarkdownEditor|Add a link (%{modifierKey}K)'), { modifierKey })
"
shortcuts="mod+k"
:shortcuts="$options.shortcuts.link"
icon="link"
/>
</div>
......
import $ from 'jquery';
import Cookies from 'js-cookie';
import Mousetrap from 'mousetrap';
import {
keysFor,
ISSUABLE_CHANGE_LABEL,
ISSUABLE_COMMENT_OR_REPLY,
ISSUABLE_EDIT_DESCRIPTION,
} from '~/behaviors/shortcuts/keybindings';
import ShortcutsIssuable from '~/behaviors/shortcuts/shortcuts_issuable';
import { parseBoolean } from '~/lib/utils/common_utils';
......@@ -10,11 +16,11 @@ export default class ShortcutsEpic extends ShortcutsIssuable {
const $issuableSidebar = $('.js-issuable-update');
Mousetrap.bind('l', () =>
Mousetrap.bind(keysFor(ISSUABLE_CHANGE_LABEL), () =>
ShortcutsEpic.openSidebarDropdown($issuableSidebar.find('.js-labels-block')),
);
Mousetrap.bind('r', ShortcutsIssuable.replyWithSelectedText);
Mousetrap.bind('e', ShortcutsIssuable.editIssue);
Mousetrap.bind(keysFor(ISSUABLE_COMMENT_OR_REPLY), ShortcutsIssuable.replyWithSelectedText);
Mousetrap.bind(keysFor(ISSUABLE_EDIT_DESCRIPTION), ShortcutsIssuable.editIssue);
}
static openSidebarDropdown($block) {
......
......@@ -2,6 +2,7 @@
import { GlTooltipDirective as GlTooltip, GlButton, GlIcon, GlLoadingIcon } from '@gitlab/ui';
import Mousetrap from 'mousetrap';
import { keysFor, ISSUABLE_CHANGE_LABEL } from '~/behaviors/shortcuts/keybindings';
import { s__, __ } from '~/locale';
import ProjectSelect from '~/vue_shared/components/sidebar/issuable_move_dropdown.vue';
import LabelsSelect from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue';
......@@ -76,10 +77,10 @@ export default {
},
mounted() {
this.sidebarEl = document.querySelector('aside.right-sidebar');
Mousetrap.bind('l', this.handleLabelsCollapsedButtonClick);
Mousetrap.bind(keysFor(ISSUABLE_CHANGE_LABEL), this.handleLabelsCollapsedButtonClick);
},
beforeDestroy() {
Mousetrap.unbind('l');
Mousetrap.unbind(keysFor(ISSUABLE_CHANGE_LABEL));
},
methods: {
handleTodoButtonClick() {
......
......@@ -5,6 +5,7 @@ import Mousetrap from 'mousetrap';
import TestCaseSidebar from 'ee/test_case_show/components/test_case_sidebar.vue';
import { mockCurrentUserTodo, mockLabels } from 'jest/issuable_list/mock_data';
import { keysFor, ISSUABLE_CHANGE_LABEL } from '~/behaviors/shortcuts/keybindings';
import ProjectSelect from '~/vue_shared/components/sidebar/issuable_move_dropdown.vue';
import LabelsSelect from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue';
......@@ -99,7 +100,10 @@ describe('TestCaseSidebar', () => {
describe('mounted', () => {
it('binds key-press listener for `l` on Mousetrap', () => {
expect(mousetrapSpy).toHaveBeenCalledWith('l', wrapper.vm.handleLabelsCollapsedButtonClick);
expect(mousetrapSpy).toHaveBeenCalledWith(
keysFor(ISSUABLE_CHANGE_LABEL),
wrapper.vm.handleLabelsCollapsedButtonClick,
);
});
});
......
......@@ -4995,6 +4995,9 @@ msgstr ""
msgid "Board|Load more issues"
msgstr ""
msgid "Bold text"
msgstr ""
msgid "Both project and dashboard_path are required"
msgstr ""
......@@ -6347,6 +6350,9 @@ msgstr ""
msgid "Close %{tabname}"
msgstr ""
msgid "Close design"
msgstr ""
msgid "Close epic"
msgstr ""
......@@ -12508,6 +12514,9 @@ msgstr ""
msgid "Expand milestones"
msgstr ""
msgid "Expand panel"
msgstr ""
msgid "Expand sidebar"
msgstr ""
......@@ -13413,6 +13422,9 @@ msgstr ""
msgid "FlowdockService|Flowdock is a collaboration web app for technical teams."
msgstr ""
msgid "Focus filter bar"
msgstr ""
msgid "FogBugz Email"
msgstr ""
......@@ -17229,6 +17241,9 @@ msgstr ""
msgid "It's you"
msgstr ""
msgid "Italic text"
msgstr ""
msgid "Iteration"
msgstr ""
......@@ -17628,21 +17643,6 @@ msgstr ""
msgid "KeyboardKey|Ctrl+"
msgstr ""
msgid "KeyboardShortcuts|Commit (when editing commit message)"
msgstr ""
msgid "KeyboardShortcuts|Global Shortcuts"
msgstr ""
msgid "KeyboardShortcuts|Toggle GitLab Next"
msgstr ""
msgid "KeyboardShortcuts|Toggle the Performance Bar"
msgstr ""
msgid "KeyboardShortcuts|Web IDE"
msgstr ""
msgid "Keys"
msgstr ""
......@@ -18337,6 +18337,9 @@ msgstr ""
msgid "Link copied"
msgstr ""
msgid "Link text"
msgstr ""
msgid "Link title"
msgstr ""
......@@ -19889,6 +19892,9 @@ msgstr ""
msgid "Mirroring will only be available if the feature is included in the plan of the selected group or user."
msgstr ""
msgid "Miscellaneous"
msgstr ""
msgid "Missing"
msgstr ""
......@@ -20627,6 +20633,9 @@ msgstr ""
msgid "Next commit"
msgstr ""
msgid "Next design"
msgstr ""
msgid "Next file in diff"
msgstr ""
......@@ -23128,6 +23137,9 @@ msgstr ""
msgid "Previous commit"
msgstr ""
msgid "Previous design"
msgstr ""
msgid "Previous file in diff"
msgstr ""
......@@ -31768,6 +31780,9 @@ msgstr ""
msgid "Toggle focus mode"
msgstr ""
msgid "Toggle keyboard shortcuts help dialog"
msgstr ""
msgid "Toggle navigation"
msgstr ""
......@@ -33415,6 +33430,9 @@ msgstr ""
msgid "View log"
msgstr ""
msgid "View logs"
msgstr ""
msgid "View merge request"
msgstr ""
......
......@@ -2,6 +2,11 @@
import 'mousetrap';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vue from 'vue';
import {
keysFor,
MR_NEXT_UNRESOLVED_DISCUSSION,
MR_PREVIOUS_UNRESOLVED_DISCUSSION,
} from '~/behaviors/shortcuts/keybindings';
import DiscussionNavigator from '~/notes/components/discussion_navigator.vue';
import eventHub from '~/notes/event_hub';
......@@ -60,13 +65,13 @@ describe('notes/components/discussion_navigator', () => {
});
it('calls jumpToNextDiscussion when pressing `n`', () => {
Mousetrap.trigger('n');
Mousetrap.trigger(keysFor(MR_NEXT_UNRESOLVED_DISCUSSION));
expect(jumpToNextDiscussion).toHaveBeenCalled();
});
it('calls jumpToPreviousDiscussion when pressing `p`', () => {
Mousetrap.trigger('p');
Mousetrap.trigger(keysFor(MR_PREVIOUS_UNRESOLVED_DISCUSSION));
expect(jumpToPreviousDiscussion).toHaveBeenCalled();
});
......@@ -87,8 +92,8 @@ describe('notes/components/discussion_navigator', () => {
});
it('unbinds keys', () => {
expect(Mousetrap.unbind).toHaveBeenCalledWith('n');
expect(Mousetrap.unbind).toHaveBeenCalledWith('p');
expect(Mousetrap.unbind).toHaveBeenCalledWith(keysFor(MR_NEXT_UNRESOLVED_DISCUSSION));
expect(Mousetrap.unbind).toHaveBeenCalledWith(keysFor(MR_PREVIOUS_UNRESOLVED_DISCUSSION));
});
it('unbinds event hub listeners', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment