This file contains 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
// ==UserScript== | |
// @name StackOverflow close votes shortcuts | |
// @namespace https://github.com/kappa7194/stackoverflow-close-votes-shortcuts | |
// @version 0.1 | |
// @description A script to add keyboard shortcuts to StackOverflow's close votes review queue | |
// @author Albireo | |
// @match http://stackoverflow.com/review/close* | |
// @grant none | |
// ==/UserScript== | |
// ISSUES | |
// - If the user presses ESC to close the dialog while in a text box the script breaks (does not update the state accordingly); | |
// - If the user uses the mouse to choose an action the script breaks (does not update the state accordingly); | |
// - This is probably fixed by moving the keyCode check for ESC before the check for the target.tagName; | |
(function () { | |
'use strict'; | |
$(document).ready(function () { | |
var keys = { | |
'Esc': 27, | |
'Enter': 13, | |
'One': 49, | |
'Two': 50, | |
'Three': 51, | |
'Four': 52, | |
'Five': 53, | |
'Six': 54, | |
'Seven': 55, | |
'Eight': 56, | |
'Nine': 57, | |
'Zero': 48 | |
}; | |
var states = { | |
atQuestion: 0, | |
atCloseReason: 1, | |
atDuplicate: 2, | |
atOffTopic: 3, | |
atOtherSite: 4 | |
}; | |
var state = states.atQuestion; | |
var clickElement = function (selector) { | |
$(selector).focus().click(); | |
}; | |
var clickAction = function (action) { | |
clickElement('.review-actions [value="' + action + '"]'); | |
}; | |
var clickCloseReason = function (reason) { | |
clickElement('[name="close-reason"][value="' + reason + '"]'); | |
}; | |
var clickOffTopicReason = function (reason) { | |
clickElement('[name="close-as-off-topic-reason"][value="' + reason + '"]'); | |
}; | |
var clickOtherSite = function (site) { | |
clickElement('[name="migration"][value="' + site + '"]'); | |
}; | |
var keyHandler = function(key) { | |
switch (state) { | |
case states.atQuestion: | |
actionHandler(key); | |
break; | |
case states.atCloseReason: | |
closeReasonHandler(key); | |
break; | |
case states.atOffTopic: | |
offTopicHandler(key); | |
break; | |
case states.atOtherSite: | |
otherSiteHandler(key); | |
break; | |
} | |
}; | |
var actionHandler = function (key) { | |
switch (key) { | |
case keys.One: // Leave Open | |
clickAction('Leave Open'); | |
resetState(); | |
break; | |
case keys.Two: // Close | |
state = states.atCloseReason; | |
clickAction('Close'); | |
break; | |
case keys.Three: // Edit | |
clickAction('Edit'); | |
resetState(); | |
break; | |
case keys.Four: // Skip | |
clickAction('Skip'); | |
resetState(); | |
break; | |
} | |
}; | |
var closeReasonHandler = function (key) { | |
switch (key) { | |
case keys.One: // Duplicate | |
clickCloseReason('Duplicate'); | |
state = states.atDuplicate; | |
break; | |
case keys.Two: // Off Topic | |
clickCloseReason('OffTopic'); | |
state = states.atOffTopic; | |
break; | |
case keys.Three: // Unclear | |
clickCloseReason('Unclear'); | |
break; | |
case keys.Four: // Too Broad | |
clickCloseReason('TooBroad'); | |
break; | |
case keys.Five: // Opinion Based | |
clickCloseReason('OpinionBased'); | |
break; | |
} | |
}; | |
var offTopicHandler = function (key) { | |
switch (key) { | |
case keys.One: // Super User | |
clickOffTopicReason('4'); | |
break; | |
case keys.Two: // Server Fault | |
clickOffTopicReason('7'); | |
break; | |
case keys.Three: // Recomment Or Find | |
clickOffTopicReason('16'); | |
break; | |
case keys.Four: // Debugging Help | |
clickOffTopicReason('13'); | |
break; | |
case keys.Five: // Typogrgaphical Error | |
clickOffTopicReason('11'); | |
break; | |
case keys.Six: // Another Site | |
state = states.atOtherSite; | |
clickOffTopicReason('2'); | |
break; | |
case keys.Seven: // Other | |
clickOffTopicReason('3'); | |
break; | |
} | |
}; | |
var otherSiteHandler = function (key) { | |
switch (key) { | |
case keys.One: // Meta | |
clickOtherSite('meta.stackoverflow.com'); | |
break; | |
case keys.Two: // Super User | |
clickOtherSite('superuser.com'); | |
break; | |
case keys.Three: // TeX | |
clickOtherSite('tex.stackexchange.com'); | |
break; | |
case keys.Four: // DBA | |
clickOtherSite('dba.stackexchange.com'); | |
break; | |
case keys.Five: // Stats | |
clickOtherSite('stats.stackexchange.com'); | |
break; | |
} | |
}; | |
var resetState = function () { | |
state = states.atQuestion; | |
}; | |
$(document).on('click', '#popup-close-question .popup-close a', function () { | |
resetState(); | |
}); | |
$(document).on('click', '#popup-close-question .popup-submit', function () { | |
resetState(); | |
}); | |
$(document).on('keyup', function (e) { | |
if ((e.target.tagName === 'INPUT' && e.target.type === 'text') || e.target.tagName === 'TEXTAREA') { | |
return; | |
} | |
switch (e.keyCode) { | |
case keys.Esc: // Close pop-up | |
resetState(); | |
break; | |
default: | |
keyHandler(e.keyCode); | |
break; | |
} | |
}); | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment