diff options
Diffstat (limited to 'app/assets/javascripts/behaviors')
9 files changed, 108 insertions, 131 deletions
diff --git a/app/assets/javascripts/behaviors/shortcuts/keybindings.js b/app/assets/javascripts/behaviors/shortcuts/keybindings.js index d173703f172..cc8a9baf69e 100644 --- a/app/assets/javascripts/behaviors/shortcuts/keybindings.js +++ b/app/assets/javascripts/behaviors/shortcuts/keybindings.js @@ -698,8 +698,8 @@ export const keybindingGroups = [ /** * Gets keyboard shortcuts associated with a command * - * @param {string} command The command object. All command - * objects are available as imports from this file. + * @param {Object} command The command object. All command objects are + * available as imports from this file. * * @returns {string[]} An array of keyboard shortcut strings bound to the command * diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js index 301dd1c5669..5c6e4665a5c 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js @@ -1,7 +1,7 @@ import $ from 'jquery'; import { flatten } from 'lodash'; -import Mousetrap from 'mousetrap'; import Vue from 'vue'; +import { Mousetrap, addStopCallback } from '~/lib/mousetrap'; import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils'; import findAndFollowLink from '~/lib/utils/navigation_utility'; @@ -28,20 +28,11 @@ import { } from './keybindings'; import { disableShortcuts, shouldDisableShortcuts } from './shortcuts_toggle'; -const defaultStopCallback = Mousetrap.prototype.stopCallback; -Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) { - if (keysFor(TOGGLE_MARKDOWN_PREVIEW).indexOf(combo) !== -1) { - return false; - } - - return defaultStopCallback.call(this, e, element, combo); -}; - /** * The key used to save and fetch the local Mousetrap instance * attached to a `<textarea>` element using `jQuery.data` */ -const LOCAL_MOUSETRAP_DATA_KEY = 'local-mousetrap-instance'; +export const LOCAL_MOUSETRAP_DATA_KEY = 'local-mousetrap-instance'; /** * Gets a mapping of toolbar button => keyboard shortcuts @@ -76,54 +67,38 @@ export default class Shortcuts { this.helpModalElement = null; this.helpModalVueInstance = null; - 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(HIDE_APPEARING_CONTENT), Shortcuts.hideAppearingContent); - Mousetrap.bind(keysFor(TOGGLE_CANARY), Shortcuts.onToggleCanary); - - const findFileURL = document.body.dataset.findFile; - - 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'), + this.bindCommands([ + [TOGGLE_KEYBOARD_SHORTCUTS_DIALOG, this.onToggleHelp], + [START_SEARCH, Shortcuts.focusSearch], + [FOCUS_FILTER_BAR, this.focusFilter.bind(this)], + [TOGGLE_PERFORMANCE_BAR, Shortcuts.onTogglePerfBar], + [HIDE_APPEARING_CONTENT, Shortcuts.hideAppearingContent], + [TOGGLE_CANARY, Shortcuts.onToggleCanary], + + [GO_TO_YOUR_TODO_LIST, () => findAndFollowLink('.shortcuts-todos')], + [GO_TO_ACTIVITY_FEED, () => findAndFollowLink('.dashboard-shortcuts-activity')], + [GO_TO_YOUR_ISSUES, () => findAndFollowLink('.dashboard-shortcuts-issues')], + [GO_TO_YOUR_MERGE_REQUESTS, () => findAndFollowLink('.dashboard-shortcuts-merge_requests')], + [GO_TO_YOUR_REVIEW_REQUESTS, () => findAndFollowLink('.dashboard-shortcuts-review_requests')], + [GO_TO_YOUR_PROJECTS, () => findAndFollowLink('.dashboard-shortcuts-projects')], + [GO_TO_YOUR_GROUPS, () => findAndFollowLink('.dashboard-shortcuts-groups')], + [GO_TO_MILESTONE_LIST, () => findAndFollowLink('.dashboard-shortcuts-milestones')], + [GO_TO_YOUR_SNIPPETS, () => findAndFollowLink('.dashboard-shortcuts-snippets')], + + [TOGGLE_MARKDOWN_PREVIEW, Shortcuts.toggleMarkdownPreview], + ]); + + addStopCallback((e, element, combo) => + keysFor(TOGGLE_MARKDOWN_PREVIEW).includes(combo) ? false : undefined, ); - Mousetrap.bind(keysFor(GO_TO_YOUR_MERGE_REQUESTS), () => - findAndFollowLink('.dashboard-shortcuts-merge_requests'), - ); - Mousetrap.bind(keysFor(GO_TO_YOUR_REVIEW_REQUESTS), () => - findAndFollowLink('.dashboard-shortcuts-review_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); + const findFileURL = document.body.dataset.findFile; if (typeof findFileURL !== 'undefined' && findFileURL !== null) { - Mousetrap.bind(keysFor(GO_TO_PROJECT_FIND_FILE), () => { + this.bindCommand(GO_TO_PROJECT_FIND_FILE, () => { visitUrl(findFileURL); }); } - $(document).on('click.more_help', '.js-more-help-button', function clickMoreHelp(e) { - $(this).remove(); - e.preventDefault(); - }); - const shortcutsModalTriggerEvent = 'click.shortcutsModalTrigger'; // eslint-disable-next-line @gitlab/no-global-event-off $(document) @@ -135,6 +110,32 @@ export default class Shortcuts { } } + /** + * Bind the keyboard shortcut(s) defined by the given command to the given + * callback. + * + * @param {Object} command A command object. + * @param {Function} callback The callback to call when the command's key + * combo has been pressed. + * @returns {void} + */ + // eslint-disable-next-line class-methods-use-this + bindCommand(command, callback) { + Mousetrap.bind(keysFor(command), callback); + } + + /** + * Bind the keyboard shortcut(s) defined by the given commands to the given + * callbacks. + * + * @param {Array<[Object, Function]>} commandsAndCallbacks An array of + * command/callback pairs. + * @returns {void} + */ + bindCommands(commandsAndCallbacks) { + commandsAndCallbacks.forEach((commandAndCallback) => this.bindCommand(...commandAndCallback)); + } + onToggleHelp(e) { if (e?.preventDefault) { e.preventDefault(); diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js index ab7fcbb35f1..65ae67d156f 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_blob.js @@ -1,5 +1,4 @@ -import Mousetrap from 'mousetrap'; -import { keysFor, PROJECT_FILES_GO_TO_PERMALINK } from '~/behaviors/shortcuts/keybindings'; +import { PROJECT_FILES_GO_TO_PERMALINK } from '~/behaviors/shortcuts/keybindings'; import { getLocationHash, updateHistory, @@ -11,7 +10,6 @@ import { updateRefPortionOfTitle } from '~/repository/utils/title'; import Shortcuts from './shortcuts'; const defaults = { - skipResetBindings: false, fileBlobPermalinkUrl: null, fileBlobPermalinkUrlElement: null, }; @@ -24,12 +22,12 @@ function eventHasModifierKeys(event) { export default class ShortcutsBlob extends Shortcuts { constructor(opts) { const options = { ...defaults, ...opts }; - super(options.skipResetBindings); + super(); this.options = options; this.shortcircuitPermalinkButton(); - Mousetrap.bind(keysFor(PROJECT_FILES_GO_TO_PERMALINK), this.moveToFilePermalink.bind(this)); + this.bindCommand(PROJECT_FILES_GO_TO_PERMALINK, this.moveToFilePermalink.bind(this)); } moveToFilePermalink() { diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js index 992e571e596..f26878cf161 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_find_file.js @@ -1,4 +1,3 @@ -import Mousetrap from 'mousetrap'; import { keysFor, PROJECT_FILES_MOVE_SELECTION_UP, @@ -6,15 +5,14 @@ import { PROJECT_FILES_OPEN_SELECTION, PROJECT_FILES_GO_BACK, } from '~/behaviors/shortcuts/keybindings'; +import { addStopCallback } from '~/lib/mousetrap'; import ShortcutsNavigation from './shortcuts_navigation'; export default class ShortcutsFindFile extends ShortcutsNavigation { constructor(projectFindFile) { super(); - const oldStopCallback = Mousetrap.prototype.stopCallback; - - Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) { + addStopCallback((e, element, combo) => { if ( element === projectFindFile.inputElement[0] && (keysFor(PROJECT_FILES_MOVE_SELECTION_UP).includes(combo) || @@ -27,12 +25,14 @@ export default class ShortcutsFindFile extends ShortcutsNavigation { return false; } - return oldStopCallback.call(this, e, element, combo); - }; + return undefined; + }); - 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); + this.bindCommands([ + [PROJECT_FILES_MOVE_SELECTION_UP, projectFindFile.selectRowUp], + [PROJECT_FILES_MOVE_SELECTION_DOWN, projectFindFile.selectRowDown], + [PROJECT_FILES_GO_BACK, projectFindFile.goToTree], + [PROJECT_FILES_OPEN_SELECTION, projectFindFile.goToBlob], + ]); } } diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js index 64297da39cd..0c882ff9ea2 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_issuable.js @@ -1,6 +1,5 @@ import $ from 'jquery'; import ClipboardJS from 'clipboard'; -import Mousetrap from 'mousetrap'; import { getSelectedFragment } from '~/lib/utils/common_utils'; import { isElementVisible } from '~/lib/utils/dom_utils'; import { DEBOUNCE_DROPDOWN_DELAY } from '~/sidebar/components/labels/labels_select_widget/constants'; @@ -9,7 +8,6 @@ import { s__ } from '~/locale'; 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, @@ -32,18 +30,14 @@ export default class ShortcutsIssuable extends Shortcuts { toast(s__('GlobalShortcuts|Unable to copy the source branch name at this time.')); }); - 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), () => this.copyBranchName()); + this.bindCommands([ + [ISSUE_MR_CHANGE_ASSIGNEE, () => ShortcutsIssuable.openSidebarDropdown('assignee')], + [ISSUE_MR_CHANGE_MILESTONE, () => ShortcutsIssuable.openSidebarDropdown('milestone')], + [ISSUABLE_CHANGE_LABEL, () => ShortcutsIssuable.openSidebarDropdown('labels')], + [ISSUABLE_COMMENT_OR_REPLY, ShortcutsIssuable.replyWithSelectedText], + [ISSUABLE_EDIT_DESCRIPTION, ShortcutsIssuable.editIssue], + [MR_COPY_SOURCE_BRANCH_NAME, () => this.copyBranchName()], + ]); /** * We're attaching a global focus event listener on document for diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js index 33a71c3a65b..bd08dc28f7a 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_navigation.js @@ -1,8 +1,6 @@ -import Mousetrap from 'mousetrap'; import { visitUrl, constructWebIDEPath } from '~/lib/utils/url_utility'; import findAndFollowLink from '~/lib/utils/navigation_utility'; import { - keysFor, GO_TO_PROJECT_OVERVIEW, GO_TO_PROJECT_ACTIVITY_FEED, GO_TO_PROJECT_RELEASES, @@ -28,40 +26,26 @@ export default class ShortcutsNavigation extends Shortcuts { constructor() { super(); - 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-deployments-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(GO_TO_PROJECT_WEBIDE), ShortcutsNavigation.navigateToWebIDE); - Mousetrap.bind(keysFor(NEW_ISSUE), () => findAndFollowLink('.shortcuts-new-issue')); + this.bindCommands([ + [GO_TO_PROJECT_OVERVIEW, () => findAndFollowLink('.shortcuts-project')], + [GO_TO_PROJECT_ACTIVITY_FEED, () => findAndFollowLink('.shortcuts-project-activity')], + [GO_TO_PROJECT_RELEASES, () => findAndFollowLink('.shortcuts-deployments-releases')], + [GO_TO_PROJECT_FILES, () => findAndFollowLink('.shortcuts-tree')], + [GO_TO_PROJECT_COMMITS, () => findAndFollowLink('.shortcuts-commits')], + [GO_TO_PROJECT_JOBS, () => findAndFollowLink('.shortcuts-builds')], + [GO_TO_PROJECT_REPO_GRAPH, () => findAndFollowLink('.shortcuts-network')], + [GO_TO_PROJECT_REPO_CHARTS, () => findAndFollowLink('.shortcuts-repository-charts')], + [GO_TO_PROJECT_ISSUES, () => findAndFollowLink('.shortcuts-issues')], + [GO_TO_PROJECT_ISSUE_BOARDS, () => findAndFollowLink('.shortcuts-issue-boards')], + [GO_TO_PROJECT_MERGE_REQUESTS, () => findAndFollowLink('.shortcuts-merge_requests')], + [GO_TO_PROJECT_WIKI, () => findAndFollowLink('.shortcuts-wiki')], + [GO_TO_PROJECT_SNIPPETS, () => findAndFollowLink('.shortcuts-snippets')], + [GO_TO_PROJECT_KUBERNETES, () => findAndFollowLink('.shortcuts-kubernetes')], + [GO_TO_PROJECT_ENVIRONMENTS, () => findAndFollowLink('.shortcuts-environments')], + [GO_TO_PROJECT_METRICS, () => findAndFollowLink('.shortcuts-metrics')], + [GO_TO_PROJECT_WEBIDE, ShortcutsNavigation.navigateToWebIDE], + [NEW_ISSUE, () => findAndFollowLink('.shortcuts-new-issue')], + ]); } static navigateToWebIDE() { diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js index c33c092b009..02c6af53fc2 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_network.js @@ -1,6 +1,4 @@ -import Mousetrap from 'mousetrap'; import { - keysFor, REPO_GRAPH_SCROLL_BOTTOM, REPO_GRAPH_SCROLL_DOWN, REPO_GRAPH_SCROLL_LEFT, @@ -14,11 +12,13 @@ export default class ShortcutsNetwork extends ShortcutsNavigation { constructor(graph) { super(); - 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); + this.bindCommands([ + [REPO_GRAPH_SCROLL_LEFT, graph.scrollLeft], + [REPO_GRAPH_SCROLL_RIGHT, graph.scrollRight], + [REPO_GRAPH_SCROLL_UP, graph.scrollUp], + [REPO_GRAPH_SCROLL_DOWN, graph.scrollDown], + [REPO_GRAPH_SCROLL_TOP, graph.scrollTop], + [REPO_GRAPH_SCROLL_BOTTOM, graph.scrollBottom], + ]); } } diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js index 66aa1b752ae..3f3e0c51de5 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_toggle.js @@ -1,4 +1,4 @@ -import Mousetrap from 'mousetrap'; +import { Mousetrap } from '~/lib/mousetrap'; import 'mousetrap/plugins/pause/mousetrap-pause'; const shorcutsDisabledKey = 'shortcutsDisabled'; diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js index b2801f9118d..62d612cfa6d 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts_wiki.js @@ -1,12 +1,12 @@ -import Mousetrap from 'mousetrap'; import findAndFollowLink from '~/lib/utils/navigation_utility'; -import { keysFor, EDIT_WIKI_PAGE } from './keybindings'; +import { EDIT_WIKI_PAGE } from './keybindings'; import ShortcutsNavigation from './shortcuts_navigation'; export default class ShortcutsWiki extends ShortcutsNavigation { constructor() { super(); - Mousetrap.bind(keysFor(EDIT_WIKI_PAGE), ShortcutsWiki.editWiki); + + this.bindCommand(EDIT_WIKI_PAGE, ShortcutsWiki.editWiki); } static editWiki() { |