diff --git a/4chan_x.coffee b/4chan_x.coffee index a6584d3d7..2584e10d4 100644 --- a/4chan_x.coffee +++ b/4chan_x.coffee @@ -11,6 +11,7 @@ config = 'Reply Hiding': [true, 'Hide single replies'] 'Show Stubs': [true, 'Of hidden threads / replies'] 'Thread Navigation': [true, 'Navigate to previous / next thread'] + 'Keyboard Navigation': [true, 'Navigate threads w/ your keyboard'] 'Reply Navigation': [true, 'Navigate to the beginning / end of a thread'] 'Thread Watcher': [true, 'Bookmark threads'] 'Thread Expansion': [true, 'View all replies'] @@ -354,6 +355,27 @@ iframeLoad = -> remove qr recaptchaReload() +keyboardNav = (e) -> + hash = Number(location.hash?.substring(1)) or 0 + switch e.keyCode + when 71 #g + if e.shiftKey + location.hash = 'navbot' + else + location.hash = 'navtop' + when 72 #h + if g.PAGENUM > 0 + location.pathname = "/#{g.BOARD}/#{g.PAGENUM - 1}#1" + when 74 #j + if hash < 10 + location.hash = hash + 1 + when 75 #k + if hash > 0 + location.hash = hash - 1 or 'navtop' + when 76 #l + if g.PAGENUM < 15 + location.pathname = "/#{g.BOARD}/#{g.PAGENUM + 1}#1" + nodeInserted = (e) -> target = e.target if target.nodeName is 'TABLE' @@ -872,7 +894,10 @@ if g.REPLY if text d.title = "/#{g.BOARD}/ - #{text}" -else +else #not reply + if getConfig 'Keyboard Navigation' + d.addEventListener 'keydown', keyboardNav, true + if getConfig 'Thread Hiding' delform = $('form[name=delform]') #don't confuse other scripts diff --git a/4chan_x.js b/4chan_x.js index cb12b3445..38246666e 100644 --- a/4chan_x.js +++ b/4chan_x.js @@ -1,11 +1,12 @@ (function() { - var $, $$, AEOS, DAY, _, _i, _len, _ref, _ref2, a, addTo, arr, as, autoWatch, autohide, b, board, callback, clearHidden, close, config, cooldown, cutoff, d, delform, down, editSauce, el, expandComment, expandThread, formSubmit, g, getConfig, getTime, hide, hideReply, hideThread, href, html, i, i1, id, iframe, iframeLoad, inAfter, inBefore, inputs, l, l1, lastChecked, m, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, options, optionsClose, parseResponse, pathname, quickReply, recaptcha, recaptchaListener, recaptchaReload, redirect, remove, replace, replyNav, report, show, showReply, showThread, slice, span, stopPropagation, temp, text, textContent, thread, threadF, threads, tn, up, watch, watchX, watcher, watcherUpdate, x; + var $, $$, AEOS, DAY, _, _i, _len, _ref, _ref2, a, addTo, arr, as, autoWatch, autohide, b, board, callback, clearHidden, close, config, cooldown, cutoff, d, delform, down, editSauce, el, expandComment, expandThread, formSubmit, g, getConfig, getTime, hide, hideReply, hideThread, href, html, i, i1, id, iframe, iframeLoad, inAfter, inBefore, inputs, keyboardNav, l, l1, lastChecked, m, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, options, optionsClose, parseResponse, pathname, quickReply, recaptcha, recaptchaListener, recaptchaReload, redirect, remove, replace, replyNav, report, show, showReply, showThread, slice, span, stopPropagation, temp, text, textContent, thread, threadF, threads, tn, up, watch, watchX, watcher, watcherUpdate, x; var __slice = Array.prototype.slice, __hasProp = Object.prototype.hasOwnProperty; config = { 'Thread Hiding': [true, 'Hide entire threads'], 'Reply Hiding': [true, 'Hide single replies'], 'Show Stubs': [true, 'Of hidden threads / replies'], 'Thread Navigation': [true, 'Navigate to previous / next thread'], + 'Keyboard Navigation': [true, 'Navigate threads w/ your keyboard'], 'Reply Navigation': [true, 'Navigate to the beginning / end of a thread'], 'Thread Watcher': [true, 'Bookmark threads'], 'Thread Expansion': [true, 'View all replies'], @@ -439,6 +440,22 @@ } return recaptchaReload(); }; + keyboardNav = function(e) { + var hash; + hash = Number(location.hash == null ? undefined : location.hash.substring(1)) || 0; + switch (e.keyCode) { + case 71: + return e.shiftKey ? (location.hash = 'navbot') : (location.hash = 'navtop'); + case 72: + return g.PAGENUM > 0 ? (location.pathname = ("/" + (g.BOARD) + "/" + (g.PAGENUM - 1) + "#1")) : null; + case 74: + return hash < 10 ? (location.hash = hash + 1) : null; + case 75: + return hash > 0 ? (location.hash = hash - 1 || 'navtop') : null; + case 76: + return g.PAGENUM < 15 ? (location.pathname = ("/" + (g.BOARD) + "/" + (g.PAGENUM + 1) + "#1")) : null; + } + }; nodeInserted = function(e) { var _i, _len, _ref, _result, callback, qr, target; target = e.target; @@ -1118,6 +1135,9 @@ } } } else { + if (getConfig('Keyboard Navigation')) { + d.addEventListener('keydown', keyboardNav, true); + } if (getConfig('Thread Hiding')) { delform = $('form[name=delform]'); d.addEventListener('DOMNodeInserted', stopPropagation, true);