/******************************************* * * * This util was created by Marius Olbertz * * Please thank Marius on GitHub /owlbertz * * or the web http://www.mariusolbertz.de/ * * * ******************************************/ !function($, Foundation){ 'use strict'; Foundation.Keyboard = {}; var keyCodes = { 9: 'TAB', 13: 'ENTER', 27: 'ESCAPE', 32: 'SPACE', 37: 'ARROW_LEFT', 38: 'ARROW_UP', 39: 'ARROW_RIGHT', 40: 'ARROW_DOWN' }; /* * Constants for easier comparing. * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE */ var keys = (function(kcs) { var k = {}; for (var kc in kcs) k[kcs[kc]] = kcs[kc]; return k; })(keyCodes); Foundation.Keyboard.keys = keys; /** * Parses the (keyboard) event and returns a String that represents its key * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE * @param {Event} event - the event generated by the event handler * @return String key - String that represents the key pressed */ var parseKey = function(event) { var key = keyCodes[event.which || event.keyCode] || String.fromCharCode(event.which).toUpperCase(); if (event.shiftKey) key = 'SHIFT_' + key; if (event.ctrlKey) key = 'CTRL_' + key; if (event.altKey) key = 'ALT_' + key; return key; }; Foundation.Keyboard.parseKey = parseKey; // plain commands per component go here, ltr and rtl are merged based on orientation var commands = {}; /** * Handles the given (keyboard) event * @param {Event} event - the event generated by the event handler * @param {String} component - Foundation component's name, e.g. Slider or Reveal * @param {Objects} functions - collection of functions that are to be executed */ var handleKey = function(event, component, functions) { var commandList = commands[component], keyCode = parseKey(event), cmds, command, fn; if (!commandList) return console.warn('Component not defined!'); if (typeof commandList.ltr === 'undefined') { // this component does not differentiate between ltr and rtl cmds = commandList; // use plain list } else { // merge ltr and rtl: if document is rtl, rtl overwrites ltr and vice versa if (Foundation.rtl()) cmds = $.extend({}, commandList.ltr, commandList.rtl); else cmds = $.extend({}, commandList.rtl, commandList.ltr); } command = cmds[keyCode]; fn = functions[command]; if (fn && typeof fn === 'function') { // execute function if exists fn.apply(); if (functions.handled || typeof functions.handled === 'function') { // execute function when event was handled functions.handled.apply(); } } else { if (functions.unhandled || typeof functions.unhandled === 'function') { // execute function when event was not handled functions.unhandled.apply(); } } }; Foundation.Keyboard.handleKey = handleKey; /** * Finds all focusable elements within the given `$element` * @param {jQuery} $element - jQuery object to search within * @return {jQuery} $focusable - all focusable elements within `$element` */ var findFocusable = function($element) { return $element.find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]').filter(function() { if (!$(this).is(':visible') || $(this).attr('tabindex') < 0) { return false; } //only have visible elements and those that have a tabindex greater or equal 0 return true; }); }; Foundation.Keyboard.findFocusable = findFocusable; /** * Returns the component name name * @param {Object} component - Foundation component, e.g. Slider or Reveal * @return String componentName */ var register = function(componentName, cmds) { commands[componentName] = cmds; }; Foundation.Keyboard.register = register; }(jQuery, window.Foundation);