#  Keyboard Shortcut Module

## Purpose of this Module Type

A Keyboard Shortcut plugin module defines a keyboard shortcut within Bitbucket Server. A
Bitbucket Server keyboard shortcut allows you to perform potentially any action in Bitbucket Server
using one or more keyboard strokes – for example, navigating to a repository,
viewing commits or browsing files.

## Configuration

The root element for the Keyboard Shortcut plugin module is `keyboard-shortcut`. It allows the following attributes and child elements for
configuration:

#### Attributes

<table>
    <tr>
        <th>Name</th>
        <th>Required</th>
        <th>Description</th>
        <th>Default</th>
    </tr>
    <tr>
        <td>key</td>
        <td><span class="tick" /></td>
        <td>
            The identifier of the plugin module. This key must be unique within the plugin where it is defined.

            <p />

            <span class="aui-icon aui-icon-info" ></span>
            Sometimes, in other contexts, you may need to uniquely identify a module.
            Do this with the <b>complete module key</b>.
            A module with key <code>fred</code> in a plugin with key <code>com.example.modules</code> will have a
            complete key of <code>com.example.modules:fred</code>.
        </td>
        <td>N/A</td>
    </tr>
    <tr>
        <td>i18n-name</td>
        <td></td>
        <td>The localisation key for the human-readable name of the plugin module.</td>
        <td></td>
    </tr>
    <tr>
        <td>name</td>
        <td></td>
        <td>The human-readable name of the plugin module.</td>
        <td>The plugin key.</td>
    </tr>
    <tr>
        <td>hidden</td>
        <td></td>
        <td>
            When <code>hidden='true'</code>, the keyboard shortcut will not appear in the Keyboard
            Shortcuts dialog box.

            <p />

            <span class="aui-icon aui-icon-info" ></span>
            Despite not appearing in the dialog box, hidden
            keyboard shortcuts can still be accessed via the relevant keystrokes.
        </td>
        <td>false</td>
    </tr>
</table>

#### Elements

<table>
    <tr>
        <th>Name</th>
        <th>Required</th>
        <th>Description</th>
    </tr>
    <tr>
        <td>order</td>
        <td><span class="tick" /></td>
        <td>
            A value that determines the order in which the shortcut appears on the
            Keyboard Shortcuts dialog box, with respect to other `keyboard-shortcut`
            plugin modules.
            <p/>
            <span class="aui-icon aui-icon-info" ></span>
            For each <code>keyboard-shortcut</code> plugin module, we
            recommend using gaps in <code>order</code> values (for example, <code>10</code>, <code>20</code>, <code>30</code>, etc.)
            rather than consecutive values. This will allow you to insert new keyboard
            shortcuts more easily into the keyboard shortcuts dialog box.
        </td>
    </tr>
    <tr>
        <td>description</td>
        <td><span class="tick" /></td>
        <td>A human-readable description of this Keyboard Shortcut module.</td>
    </tr>
    <tr>
        <td>shortcut</td>
        <td><span class="tick" /></td>
        <td>
            The sequence of keystrokes required to activate the keyboard shortcut. These
            should be presented in the order that the keys are pressed on a keyboard. For
            example, <code>gb</code> represents a keyboard shortcut activated by pressing '<code>g</code>' then
            '<code>b</code>' on the keyboard.
        </td>
    </tr>
    <tr>
        <td>operation</td>
        <td><span class="tick" /></td>
        <td>
            Defines the action to take when this shortcut is activated. The available
            actions come from <a href="https://docs.atlassian.com/aui/latest/docs/keyboard-shortcuts.html">AJS.whenIType</a>. The action is specified through the `type`
            attribute of the operation element. The text content of this element is used
            as a parameter to the AJS.whenIType function being called. Usually the
            parameter is a <a href="http://api.jquery.com/category/selectors/">jQuery selector</a>
            that specifies the target of the keyboard shortcut.

            Some actions take an optional second parameter. If you require specifying
            multiple parameters, you may use a strict JSON array as the operation
            element's text content, and this will be used as the `arguments` of the
            function.

            Available types are:

            <ul>
                <li>
                    <b>click</b><br/>
                    Clicks an element identified by a jQuery selector
                </li>

                <li>
                    <b>execute</b><br/>
                    Executes JavaScript in a scoped context (any vars you create will not be
                    available to other code).
                </li>

                <li>
                    <b>followLink</b><br/>
                    Sets the window.location to the href value of the link specified by the jQuery
                    selector.
                </li>

                <li>
                    <b>goTo</b><br/>
                    Changes the window.location to go to a specified location
                </li>

                <li>
                    <b>moveToAndClick</b><br/>
                    Scrolls the window to an element and clicks that element using a jQuery selector
                </li>

                <li>
                    <b>moveToAndFocus</b><br/>
                    Scrolls the window to an element specified by a jQuery selector and focuses that element.
                </li>

                <li>
                    <b>moveToNextItem</b><br/>
                    Scrolls to and adds a "focused" class to the next item in the jQuery collection
                </li>

                <li>
                    <b>moveToPrevItem</b><br/>
                    Scrolls to and adds a "focused" class to the previous item in the jQuery collection
                </li>
             </ul>
        </td>
    </tr>
    <tr>
        <td>context</td>
        <td><span class="tick" /></td>
        <td>
            The context defines which pages the shortcut will be active on.
            <ul>

                <li>
                If this element contains <code>global</code> the keyboard shortcut will be active on all Bitbucket Server pages.
                The shortcut will also appear in the 'Global Shortcuts' sub-section of the Keyboard Shortcuts dialog box.
                Other built-in contexts are <code>branch</code> (for branch/tag specific pages within a repository), <code>commit</code>
                (when viewing a single commit), <code>commits</code> (when viewing the list of commits), <code>filebrowser</code>
                (when viewing a directory within a repository), and <code>sourceview</code> (when viewing a single file's source or diff).
                You may specify your own arbitrary contexts, but you will have to manually
                <a href="keyboard-shortcut.html#Enabling_Custom_Contexts">enable that context</a> on any page where you'd like your shortcuts to run.
                Note that the string you use for your custom context will also be used as its header text within the shortcut help dialog.
                E.g., "my context" will be displayed under the header "My Context" in the dialog.
                </li>
            </ul>

        </td>
    </tr>
</table>


## Examples

These examples are taken from Bitbucket Server's pre-defined keyboard shortcuts:

```xml
...
    <keyboard-shortcut key="shortcut-branch-selector" i18n-name="bitbucket.web.keyboardshortcut.branch.selector" name="Open Branch Selector">
        <description key="bitbucket.web.keyboardshortcut.branch.selector.desc">Change branch/tag</description>
        <shortcut>b</shortcut>
        <operation type="click">#repository-layout-revision-selector</operation>
        <context>branch</context>
    </keyboard-shortcut>
...

...
    <keyboard-shortcut key="shortcut-commit-move-to-next-file" i18n-name="bitbucket.web.keyboardshortcut.commit.next.file" name="Commit - Open next file">
        <description key="bitbucket.web.keyboardshortcut.commit.next.file.desc">Next file</description>
        <shortcut>j</shortcut>
        <operation type="evaluate">require('util/shortcuts').setup('requestMoveToNextHandler', this, 'j');</operation>
        <context>commit</context>
    </keyboard-shortcut>
...
```
## Enabling Custom Contexts

Enabling a custom context requires handling of the "register-contexts.keyboardshortcuts" AJS event from JavaScript.
In Bitbucket Server, this is also exposed as an event on 'util/events' if you prefer that API.

```javascript
AJS.bind("register-contexts.keyboardshortcuts", function(e, data) {
    data.shortcutRegistry.enableContext('my context');
});
```

or

```javascript
require('util/events').on('stash.widget.keyboard-shortcuts.register-contexts', function(registry) {
    registry.enableContext('my context');
});
```
