/** * @provides javelin-behavior-releeph-request-state-change * @requires javelin-behavior * javelin-dom * javelin-stratcom * javelin-request * phabricator-keyboard-shortcut * phabricator-notification */ JX.behavior('releeph-request-state-change', function(config) { var root = JX.DOM.find(document, 'div', 'releeph-request-header-list'); function getRequestHeaderNodes() { return JX.DOM.scry(root, 'div', 'releeph-request-header'); } /** * Keyboard navigation */ var keynav_cursor = -1; var notification = new JX.Notification(); function keynavJump(manager, delta) { // Calculate this everytime, because the DOM changes. var headers = getRequestHeaderNodes(); keynav_cursor += delta; if (keynav_cursor < 0) { keynav_cursor = -1; window.scrollTo(0); keynavMarkup(); return; } if (keynav_cursor >= headers.length) { keynav_cursor = headers.length - 1; } var focus = headers[keynav_cursor]; manager.scrollTo(focus); keynavMarkup(); } function keynavMarkup() { var headers = getRequestHeaderNodes(); for (var k in headers) { JX.DOM.alterClass(headers[k], 'focus', k == keynav_cursor); } } function keynavAction(manager, action_name) { var headers = getRequestHeaderNodes(); var header = headers[keynav_cursor]; if (keynav_cursor < 0) { return; } var sigil = action_name; var button = JX.DOM.find(header, 'a', sigil); if (button) { button.click(); } } function keynavNavigateToRequestPage() { var headers = getRequestHeaderNodes(); var header = headers[keynav_cursor]; JX.DOM.find(header, 'a', 'hidden-link').click(); } new JX.KeyboardShortcut('j', 'Jump to next request.') .setHandler(function(manager) { keynavJump(manager, +1); }) .register(); new JX.KeyboardShortcut('k', 'Jump to previous request.') .setHandler(function(manager) { keynavJump(manager, -1); }) .register(); new JX.KeyboardShortcut('a', 'Approve the selected request.') .setHandler(function(manager) { keynavAction(manager, 'want'); }) .register(); new JX.KeyboardShortcut('r', 'Reject the selected request.') .setHandler(function(manager) { keynavAction(manager, 'pass'); }) .register(); new JX.KeyboardShortcut('g', "Open selected request's page in a new tab.") .setHandler(function(manager) { keynavNavigateToRequestPage(); }) .register(); /** * AJAXy state changes for request buttons. */ function request_action(node, url) { var request = new JX.Request(url, function(response) { if (config.reload) { window.location.reload(); } else { var markup = JX.$H(response.markup); JX.DOM.replace(node, markup); keynavMarkup(); } }); request.send(); } JX.Stratcom.listen( 'click', 'releeph-request-state-change', function(e) { var button = e.getNode('releeph-request-state-change'); var node = e.getNode('releeph-request-header'); var url = e.getNodeData('releeph-request-state-change'); // If this button has no action, or we've already responded to the first // click... if (!url || button.disabled) { return; } // There's a race condition here though :( JX.DOM.alterClass(button, 'disabled', true); button.disabled = true; e.prevent(); request_action(node, url); } ); });