User:RogueSly/keybinds.js

/* * Keybinds * * Keys are triggered in order, with special operation keys coming first. For example, Alt+Cmd+Ctrl+Shift+Enter */ (function {  // Use Ctrl on Macs, Alt on Windows/Unix/Linux  var ctrl = (function  { var ctrl = navigator.platform.match(/mac|apple/i) && 'Ctrl' || 'Alt'; return function (key) { return [ ctrl, key ].join('+'); }; });

var map = (function {    var map = {};    return function (key, fn) {      if (typeof key !== 'string') return map;      if (!fn) return map[key];      if (typeof fn !== 'function') return false;      return map[key] = fn;    };  });

// Random page on Ctrl+R map(ctrl('R'), function {    navigate('/wiki/Special:Random');  });

// Upload form on Ctrl+U map(ctrl('U'), function {    navigate('/wiki/Wikipedia:File_Upload_Wizard');  });

// Toggle in and out of edit mode on Ctrl+E map(ctrl('E'), function {    navigate([ location.pathname, (location.search && (location.search.match(/[?&]action=edit/i) && location.search.replace('&action=edit', ).replace('?action=edit', '?') || [ location.search, 'action=edit' ].join('&')) || 'action=edit').replace(/^\?/, ) ].filter(function (value) {     return typeof value === 'string' && value.length > 0;    }).join('?'));  });

// Toggle in and out of the current talk page on Ctrl+T map(ctrl('T'), function {    var matches = decodeURIComponent(location.pathname).match(/^\/wiki\/(.+)$/i),        split = matches && matches[1].split(':');

split.length > 1 && ((split[0] === 'Talk' && split.shift) || (split[0] === 'User_talk' && (split[0] = 'User')) || (split[0] = split[0] === 'User' && 'User_talk' || 'Talk')) || split.unshift('Talk');

navigate([     'wiki',      split.join(':')    ].join('/')); });

var keys = { 'U+0008': 'Backspace', 'U+0009': 'Tab', 'U+001B': 'Escape' };

function real(key) { var index; return typeof key === 'string' && ((!!~(index = Object.keys(keys).indexOf(key.toUpperCase)) && keys[Object.keys(map)[index]]) || key.length > 0 && !key.match(/^U\+/) && key); }

function flatten(array) { return array.map(function (value) {     return Array.isArray(value) && flatten(value) || real(value);    }).filter(function (value) {      return typeof value === 'string' && value.length > 0;    }).join('+'); }

function navigate(path) { return window.location.href = [ location.protocol, '//',     location.host, path[0] === '/' && path || '/' + path ].join(''); }

// Assign keydown function. document.onkeydown = function (event) { var index, fn;

function key(event) { var matches; return flatten([       event.altKey && 'Alt',        event.metaKey && 'Cmd',        event.ctrlKey && 'Ctrl',        event.shiftKey && 'Shift',        !~[ 'Meta', 'Alt', 'Control', 'Shift' ].indexOf(event.keyIdentifier) && [          real(event.keyIdentifier),          !~[ 'Enter', 'Escape', 'CapsLock', 'Up', 'Down', 'Left', 'Right' ].indexOf(real(event.keyIdentifier)) && typeof String.fromCharCode === 'function' && (event.keyCode === 32 && 'Space' || String.fromCharCode((matches = event.keyIdentifier.match(/^U\+([0-9a-f]+)$/i)) && parseInt(matches[1], 16) || event.keyCode || event.which).replace(/[\b\t]/, '')) || event.keyCode || event.which        ]      ]); }

~(index = Object.keys(map).indexOf(key(event))) && (fn = map(Object.keys(map)[index])) && typeof fn === 'function' && fn; }; });