handsontable
Version:
Handsontable is a JavaScript Data Grid available for React, Angular and Vue.
226 lines (217 loc) • 9.17 kB
JavaScript
;
exports.__esModule = true;
exports.isContextObject = isContextObject;
require("core-js/modules/es.error.cause.js");
require("core-js/modules/es.array.push.js");
require("core-js/modules/esnext.iterator.constructor.js");
require("core-js/modules/esnext.iterator.filter.js");
require("core-js/modules/esnext.iterator.for-each.js");
var _uniqueMap = require("../utils/dataStructures/uniqueMap");
var _utils = require("./utils");
var _mixed = require("../helpers/mixed");
var _function = require("../helpers/function");
var _object = require("../helpers/object");
var _templateLiteralTag = require("../helpers/templateLiteralTag");
const __kindOf = Symbol('shortcut-context');
/**
* Checks if the provided object is a context object.
*
* @param {*} objectToCheck An object to check.
* @returns {boolean}
*/
function isContextObject(objectToCheck) {
return (0, _object.isObject)(objectToCheck) && objectToCheck.__kindOf === __kindOf;
}
/* eslint-disable jsdoc/require-description-complete-sentence */
/**
* The `ShortcutContext` API lets you store and manage [keyboard shortcuts](@/guides/navigation/keyboard-shortcuts/keyboard-shortcuts.md) in a given [context](@/guides/navigation/keyboard-shortcuts/keyboard-shortcuts.md#keyboard-shortcut-contexts).
*
* Each `ShortcutContext` object stores and manages its own set of keyboard shortcuts.
*
* @alias ShortcutContext
* @class ShortcutContext
* @param {string} name The name of the keyboard shortcut context
* @param {string} [scope='table'] The scope of the shortcut: `'table'` or `'global'`
* @returns {object}
*/
const createContext = function (name) {
let scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'table';
const SHORTCUTS = (0, _uniqueMap.createUniqueMap)({
errorIdExists: keys => `The "${keys}" shortcut is already registered in the "${name}" context.`
});
/**
* Add a keyboard shortcut to this context.
*
* @memberof ShortcutContext#
* @param {object} options The shortcut's options
* @param {Array<Array<string>>} options.keys Names of the shortcut's keys,
* (coming from [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)),
* in lowercase or uppercase, unified across browsers
* @param {Function} options.callback The shortcut's action
* @param {object} options.group A group of shortcuts to which the shortcut belongs
* @param {object} [options.runOnlyIf] A condition on which the shortcut's action runs
* @param {object} [options.stopPropagation=false] If set to `true`: stops the event's propagation
* @param {object} [options.captureCtrl=false] If set to `true`: captures the state of the Control/Meta modifier key
* @param {object} [options.preventDefault=true] If set to `true`: prevents the default behavior
* @param {object} [options.position='after'] The order in which the shortcut's action runs:
* `'before'` or `'after'` the `relativeToGroup` group of actions
* @param {object} [options.relativeToGroup] The name of a group of actions, used to determine an action's `position`
* @param {object} [options.forwardToContext] The context object where the event will be forwarded to.
*/
const addShortcut = function () {
let {
keys,
callback,
group,
runOnlyIf = () => true,
captureCtrl = false,
preventDefault = true,
stopPropagation = false,
relativeToGroup,
position,
forwardToContext
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if ((0, _mixed.isUndefined)(group)) {
throw new Error('You need to define the shortcut\'s group.');
}
if ((0, _function.isFunction)(callback) === false) {
throw new Error('The shortcut\'s callback needs to be a function.');
}
if (Array.isArray(keys) === false) {
throw new Error((0, _templateLiteralTag.toSingleLine)`Pass the shortcut\'s keys as an array of arrays,\x20
using the KeyboardEvent.key properties:\x20
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values.`);
}
const newShortcut = {
callback,
group,
runOnlyIf,
captureCtrl,
preventDefault,
stopPropagation
};
if ((0, _mixed.isDefined)(relativeToGroup)) {
newShortcut.relativeToGroup = relativeToGroup;
newShortcut.position = position;
}
if (isContextObject(forwardToContext)) {
newShortcut.forwardToContext = forwardToContext;
}
keys.forEach(keyCombination => {
const normalizedKeys = (0, _utils.normalizeKeys)(keyCombination);
const hasKeyCombination = SHORTCUTS.hasItem(normalizedKeys);
if (hasKeyCombination) {
const shortcuts = SHORTCUTS.getItem(normalizedKeys);
let insertionIndex = shortcuts.findIndex(shortcut => shortcut.group === relativeToGroup);
if (insertionIndex !== -1) {
if (position === 'before') {
insertionIndex -= 1;
} else {
insertionIndex += 1;
}
} else {
insertionIndex = shortcuts.length;
}
shortcuts.splice(insertionIndex, 0, newShortcut);
} else {
SHORTCUTS.addItem(normalizedKeys, [newShortcut]);
}
});
};
/**
* Add multiple keyboard shortcuts to this context.
*
* @memberof ShortcutContext#
* @param {Array<object>} shortcuts List of shortcuts to add to this shortcut context
* @param {object} [options] A shortcut's options
* @param {Function} [options.callback] A shortcut's action
* @param {object} [options.group] A group of shortcuts to which a shortcut belongs
* @param {object} [options.runOnlyIf] A condition on which a shortcut's action runs
* @param {object} [options.stopPropagation=false] If set to `true`: stops the event's propagation
* @param {object} [options.preventDefault=true] If set to `true`: prevents the default behavior
* @param {object} [options.position='after'] The order in which a shortcut's action runs:
* `'before'` or `'after'` a `relativeToGroup` group of actions
* @param {object} [options.relativeToGroup] The name of a group of actions, used to determine an action's `position`
* @param {object} [options.forwardToContext] The context object where the event will be forwarded to.
*/
const addShortcuts = function (shortcuts) {
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
shortcuts.forEach(shortcut => {
(0, _object.objectEach)(options, (value, key) => {
if (Object.prototype.hasOwnProperty.call(shortcut, key) === false) {
shortcut[key] = options[key];
}
});
addShortcut(shortcut);
});
};
/**
* Remove a shortcut from this context.
*
* @memberof ShortcutContext#
* @param {Array<string>} keys Names of the shortcut's keys,
* (coming from [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)),
* in lowercase or uppercase, unified across browsers
*/
const removeShortcutsByKeys = keys => {
const normalizedKeys = (0, _utils.normalizeKeys)(keys);
SHORTCUTS.removeItem(normalizedKeys);
};
/**
* Remove a group of shortcuts from this context.
*
* @memberof ShortcutContext#
* @param {string} group The name of the group of shortcuts
*/
const removeShortcutsByGroup = group => {
const shortcuts = SHORTCUTS.getItems();
shortcuts.forEach(_ref => {
let [normalizedKeys, shortcutOptions] = _ref;
const leftOptions = shortcutOptions.filter(option => option.group !== group);
if (leftOptions.length === 0) {
removeShortcutsByKeys((0, _utils.getKeysList)(normalizedKeys));
} else {
shortcutOptions.length = 0;
shortcutOptions.push(...leftOptions);
}
});
};
/**
* Get a shortcut's details.
*
* @memberof ShortcutContext#
* @param {Array<string>} keys Names of the shortcut's keys,
* (coming from [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)),
* in lowercase or uppercase, unified across browsers
* @returns {Array}
*/
const getShortcuts = keys => {
const normalizedKeys = (0, _utils.normalizeKeys)(keys);
const shortcuts = SHORTCUTS.getItem(normalizedKeys);
return (0, _mixed.isDefined)(shortcuts) ? shortcuts.slice() : [];
};
/**
* Check if a shortcut exists in this context.
*
* @memberof ShortcutContext#
* @param {Array<string>} keys Names of the shortcut's keys,
* (coming from [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)),
* in lowercase or uppercase, unified across browsers
* @returns {boolean}
*/
const hasShortcut = keys => {
const normalizedKeys = (0, _utils.normalizeKeys)(keys);
return SHORTCUTS.hasItem(normalizedKeys);
};
return {
__kindOf,
scope,
addShortcut,
addShortcuts,
getShortcuts,
hasShortcut,
removeShortcutsByKeys,
removeShortcutsByGroup
};
};
exports.createContext = createContext;