Welcome to mirror list, hosted at ThFree Co, Russian Federation.

mousetrap.js « lib « javascripts « assets « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ef3f54ec314938e995adcc875d8731023951ef01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// This is the only file allowed to import directly from the package.
// eslint-disable-next-line no-restricted-imports
import Mousetrap from 'mousetrap';

const additionalStopCallbacks = [];
const originalStopCallback = Mousetrap.prototype.stopCallback;

Mousetrap.prototype.stopCallback = function customStopCallback(e, element, combo) {
  for (const callback of additionalStopCallbacks) {
    const returnValue = callback.call(this, e, element, combo);
    if (returnValue !== undefined) return returnValue;
  }

  return originalStopCallback.call(this, e, element, combo);
};

/**
 * Add a stop callback to Mousetrap.
 *
 * This allows overriding the default behaviour of Mousetrap#stopCallback,
 * which is to stop the bound key handler/callback from being called if the key
 * combo is pressed inside form fields (input, select, textareas, etc). See
 * https://craig.is/killing/mice#api.stopCallback.
 *
 * The stopCallback registered here has the same signature as
 * Mousetrap#stopCallback, with the one difference being that the callback
 * should return `undefined` if it has no opinion on whether the current key
 * combo should be stopped or not, and the next stop callback should be
 * consulted instead. If a boolean is returned, no other stop callbacks are
 * called.
 *
 * Note: This approach does not always work as expected when coupled with
 * Mousetrap's pause plugin, which is used for enabling/disabling all keyboard
 * shortcuts. That plugin assumes it's the first to execute and overwrite
 * Mousetrap's `stopCallback` method, whereas to work correctly with this, it
 * must execute last. This is not guaranteed or even attempted.
 *
 * To work correctly, we may need to reimplement the pause plugin here.
 *
 * @param {(e: Event, element: Element, combo: string) => boolean|undefined}
 *     stopCallback The additional stop callback function to add to the chain
 *     of stop callbacks.
 * @returns {void}
 */
export const addStopCallback = (stopCallback) => {
  // Unshift, since we want to iterate through them in reverse order, so that
  // the most recently added handler is called first, and the original
  // stopCallback method is called last.
  additionalStopCallbacks.unshift(stopCallback);
};

/**
 * Clear additionalStopCallbacks. Used only for tests.
 */
export const clearStopCallbacksForTests = () => {
  additionalStopCallbacks.length = 0;
};

export { Mousetrap };