Created
May 31, 2016 00:08
-
-
Save dadambickford/d6792fbda2ed45997f3961155704f401 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* BatchGeoKeyboardShortcuts stores and initializes all of the keyboard shortcuts | |
* for the batchgeo map. | |
*/ | |
window.BatchGeoKeyboardShortcuts = (function () { | |
/** | |
* _activeElements is a private state object for this module to keep track of which | |
* shortcut contexts are active. document and #mapWrap are active by default on | |
* page load. | |
* | |
* @type {Object} | |
*/ | |
var _activeElements = { | |
document: true, | |
'#mapWrap': true | |
} | |
/** | |
* _setActiveElements takes a click event object. It uses the click event data | |
* to tell where the user clicks and if the click is within the element context | |
* of any of our shortcuts. If it is then it sets the context true in our | |
* _activeState object. | |
* | |
* @param {object} event - click event data. | |
*/ | |
var _setActiveElements = function (event, shortcuts) { | |
// if the actual click target was the top search input, then we need to track that | |
if ($(event.target).is("#addressBox")) { | |
_activeElements.addressBox = true; | |
} | |
else { | |
_activeElements.addressBox = false; | |
} | |
// loop through our shortcuts and check if the even target is within any of | |
// our shortcut contexts. | |
shortcuts.forEach(function (shortcut) { | |
if (shortcut.context !== 'document') { | |
if ($(shortcut.context).find(event.target).length) { | |
_activeElements[shortcut.context] = true; | |
} | |
else { | |
_activeElements[shortcut.context] = false; | |
} | |
} | |
}); | |
}; | |
var _prepareShortcuts = function (shortcuts) { | |
// loop through our shortcuts and default global shortcut context to 'document' | |
// and non modifier shortcuts to always return true | |
shortcuts.forEach(function (shortcut) { | |
shortcut.context = shortcut.context || 'document'; | |
shortcut.modifier = shortcut.modifier || function () { return true; }; | |
}); | |
return shortcuts; | |
} | |
/** | |
* `shortcuts` {array} is a collection of shortcut data. A shortcut object needs | |
* to have at least a `key` prop, which is the `event.which` key code, and an | |
* `action` callback, which is the function that will be ran when the corresponding | |
* key is pressed. | |
* | |
* There are 2 optional props for shortcut data, `context` and `modifier`. `context` | |
* is the element that must be focused for the shorcut to work. `context` is | |
* optional because if a `context` is not passed then the `context` is set to | |
* `document` and the shortcut is usable on the entire page. If the shortcut | |
* should only be usuable on certain parts of the page, set the `context` prop | |
* to the `id` or `class` of the wrapping element that the shortcut should work | |
* on. | |
* | |
* The `modifier` prop is for 2 key shortcuts like `cmd`+`z`. `modifier` is a | |
* function that takes one parameter, `e`, which is the keydown event data. In | |
* this function you would return whichever modifier prop from the event data | |
* that you would like to modify your shortcut. | |
* | |
* Here is an xample of a `modifier` function that would make a normal shortcut | |
* into a `shift` + `whatever` type of shortcut. | |
* ``` | |
* modifier: function (e) { | |
* return e.shiftKey; | |
* }, | |
* ``` | |
* You can also use the modifier to prevent the shortcut from firing if a modifier | |
* key is pressed. An example of this is you want to put a shortcut on the letter | |
* 's' but don't want the shortcut to fire if the user is pressing `cmd`+`s` as | |
* if to save something. Use the modifier function to return `!e.shiftKey` or | |
* whichever modifier applies to your situation. | |
* | |
* And here is an example of a full shortcut object. | |
* ``` | |
* { | |
* key: 77, | |
* context: '.myShortcutArea', | |
* modifier: function (e) { | |
* return e.metaKey || e.ctrlKey; | |
* }, | |
* action: function () { | |
* console.log('You pressed `Ctrl`/`Cmd` + `M`!'); | |
* } | |
* } | |
* | |
*/ | |
return function shortcutInstance (shortcuts) { | |
shortcuts = _prepareShortcuts(shortcuts); | |
/** | |
* on click we want to set our active elements for shortcut context | |
* @param {object} event - click event data | |
*/ | |
var _shortcutClickHandler = function (event) { | |
_setActiveElements(event, this.shortcuts); | |
}; | |
/** | |
* on keydown loop through our shortcuts and fire any that match criteria | |
* @param {[type]} event - keydown event data | |
*/ | |
var _shortcutKeydownHandler = function (event) { | |
// if the search input is focused get outta here. | |
if (_activeElements.addressBox) return; | |
shortcuts.forEach(function (shortcut) { | |
// if all criteria (key, modifier, and context) are true then fire action | |
if (shortcut.key == event.which && shortcut.modifier(event) && _activeElements[shortcut.context]) { | |
shortcut.action(); | |
} | |
}); | |
}; | |
/** | |
* _initShortcuts sets up the necessary click and keydown listeners for all | |
* of our shortcuts to work. | |
*/ | |
var _initShortcuts = function (shortcuts) { | |
// Check shortcut context on click | |
$(document).on('click.shortcut', _shortcutClickHandler); | |
$(document).on('keydown.shortcut', _shortcutKeydownHandler); | |
}; | |
return { | |
/** | |
* enable() simply calls the `_initShortcuts` function to get everything started. | |
*/ | |
enable: function () { | |
_initShortcuts(shortcuts); | |
}, | |
/** | |
* disable() simply removes the event listeners. Nothing else to reset. | |
*/ | |
disable: function () { | |
$(document).off('click.shortcut', _shortcutClickHandler); | |
$(document).off('keydown.shortcut', _shortcutKeydownHandler); | |
} | |
}; | |
}; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment