Skip to content

Instantly share code, notes, and snippets.

@kappa7194 kappa7194/user.js

Last active Aug 29, 2015
Embed
What would you like to do?
// ==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
You can’t perform that action at this time.