From a1ed6c59b0249a1b817007673a6dc272fa93b3e2 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Tue, 6 Mar 2012 19:17:12 +0100 Subject: [PATCH] Refactor reply navigation. Close #217. --- 4chan_x.user.js | 88 +++++++++++++++++++++---------------------------- changelog | 1 + script.coffee | 79 ++++++++++++++++++++------------------------ 3 files changed, 74 insertions(+), 94 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 7fba70f22..df8a142e6 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -1050,10 +1050,10 @@ Keybinds.open(thread, true); break; case conf.nextReply: - Keybinds.hl.next(thread); + Keybinds.hl(+1, thread); break; case conf.previousReply: - Keybinds.hl.prev(thread); + Keybinds.hl(-1, thread); break; case conf.hide: ThreadHiding.toggle(thread); @@ -1159,56 +1159,43 @@ return location.href = url; } }, - hl: { - next: function(thread) { - var next, rect, replies, reply, td, top, _i, _len; - if (td = $('td.replyhl', thread)) { - td.className = 'reply'; - rect = td.getBoundingClientRect(); - if (rect.top > 0 && rect.bottom < d.body.clientHeight) { - next = $.x('following::td[@class="reply"]', td); - if ($.x('ancestor::div[@class="thread"]', next) !== thread) return; - rect = next.getBoundingClientRect(); - if (rect.top > 0 && rect.bottom < d.body.clientHeight) { - next.className = 'replyhl'; - } - return; - } + hl: function(delta, thread) { + var next, rect, replies, reply, td, _i, _len; + if (td = $('.replyhl', thread)) { + td.className = 'reply'; + td.removeAttribute('tabindex'); + rect = td.getBoundingClientRect(); + if (rect.bottom >= 0 && rect.top <= d.body.clientHeight) { + next = delta === +1 ? $.x('following::td[@class="reply"]', td) : $.x('preceding::td[@class="reply"]', td); } - replies = $$('td.reply', thread); - for (_i = 0, _len = replies.length; _i < _len; _i++) { - reply = replies[_i]; - top = reply.getBoundingClientRect().top; - if (top > 0) { - reply.className = 'replyhl'; - return; - } + if (!next) { + td.className = 'replyhl'; + td.tabIndex = 0; + next.focus(); + return; } - }, - prev: function(thread) { - var bot, height, prev, rect, replies, reply, td, _i, _len; - if (td = $('td.replyhl', thread)) { - td.className = 'reply'; - rect = td.getBoundingClientRect(); - if (rect.top > 0 && rect.bottom < d.body.clientHeight) { - prev = $.x('preceding::td[@class="reply"][1]', td); - rect = prev.getBoundingClientRect(); - if (rect.top > 0 && rect.bottom < d.body.clientHeight) { - prev.className = 'replyhl'; - } - return; - } + if (!(g.REPLY || $.x('ancestor::div[@class="thread"]', next) === thread)) { + return; } - replies = $$('td.reply', thread); - replies.reverse(); - height = d.body.clientHeight; - for (_i = 0, _len = replies.length; _i < _len; _i++) { - reply = replies[_i]; - bot = reply.getBoundingClientRect().bottom; - if (bot < height) { - reply.className = 'replyhl'; - return; - } + rect = next.getBoundingClientRect(); + if (rect.top < 0 || rect.bottom > d.body.clientHeight) { + next.scrollIntoView(delta === -1); + } + next.className = 'replyhl'; + next.tabIndex = 0; + next.focus(); + return; + } + replies = $$('.reply', thread); + if (delta === -1) replies.reverse(); + for (_i = 0, _len = replies.length; _i < _len; _i++) { + reply = replies[_i]; + rect = reply.getBoundingClientRect(); + if (delta === +1 && rect.top >= 0 || delta === -1 && rect.bottom <= d.body.clientHeight) { + reply.className = 'replyhl'; + reply.tabIndex = 0; + reply.focus(); + return; } } } @@ -1247,7 +1234,6 @@ return Nav.scroll(+1); } }, - threads: [], getThread: function(full) { var bottom, i, rect, thread, _len, _ref; Nav.threads = $$('.thread:not([hidden])'); @@ -1261,7 +1247,7 @@ return thread; } } - return null; + return $('form[name=delform]'); }, scroll: function(delta) { var i, rect, thread, top, _ref, _ref2; diff --git a/changelog b/changelog index b8311bd40..db392fa3b 100644 --- a/changelog +++ b/changelog @@ -4,6 +4,7 @@ master Threads will now be updated instantly after posting through the QR. Your own posts will not count toward the unread count after posting through the QR. QR thumbnails of high-res pictures will not slow down anymore. + Reply navigation keybinds will now scroll as you navigate. - noface Add unique ID to filter. diff --git a/script.coffee b/script.coffee index d789f4fcf..4e4fe1e41 100644 --- a/script.coffee +++ b/script.coffee @@ -888,9 +888,9 @@ Keybinds = Keybinds.open thread, true # Reply Navigation when conf.nextReply - Keybinds.hl.next thread + Keybinds.hl +1, thread when conf.previousReply - Keybinds.hl.prev thread + Keybinds.hl -1, thread when conf.hide ThreadHiding.toggle thread else @@ -943,45 +943,40 @@ Keybinds = else location.href = url - hl: - next: (thread) -> - if td = $ 'td.replyhl', thread - td.className = 'reply' - rect = td.getBoundingClientRect() - if rect.top > 0 and rect.bottom < d.body.clientHeight #you're fully visible - next = $.x 'following::td[@class="reply"]', td - return if $.x('ancestor::div[@class="thread"]', next) isnt thread - rect = next.getBoundingClientRect() - if rect.top > 0 and rect.bottom < d.body.clientHeight #and so is the next - next.className = 'replyhl' - return + hl: (delta, thread) -> + if td = $ '.replyhl', thread + td.className = 'reply' + td.removeAttribute 'tabindex' + rect = td.getBoundingClientRect() + if rect.bottom >= 0 and rect.top <= d.body.clientHeight # We're at least partially visible + next = + if delta is +1 + $.x 'following::td[@class="reply"]', td + else + $.x 'preceding::td[@class="reply"]', td + unless next + td.className = 'replyhl' + td.tabIndex = 0 + next.focus() + return + return unless g.REPLY or $.x('ancestor::div[@class="thread"]', next) is thread + rect = next.getBoundingClientRect() + if rect.top < 0 or rect.bottom > d.body.clientHeight + next.scrollIntoView delta is -1 + next.className = 'replyhl' + next.tabIndex = 0 + next.focus() + return - replies = $$ 'td.reply', thread - for reply in replies - top = reply.getBoundingClientRect().top - if top > 0 - reply.className = 'replyhl' - return - - prev: (thread) -> - if td = $ 'td.replyhl', thread - td.className = 'reply' - rect = td.getBoundingClientRect() - if rect.top > 0 and rect.bottom < d.body.clientHeight #you're fully visible - prev = $.x 'preceding::td[@class="reply"][1]', td - rect = prev.getBoundingClientRect() - if rect.top > 0 and rect.bottom < d.body.clientHeight #and so is the prev - prev.className = 'replyhl' - return - - replies = $$ 'td.reply', thread - replies.reverse() - height = d.body.clientHeight - for reply in replies - bot = reply.getBoundingClientRect().bottom - if bot < height - reply.className = 'replyhl' - return + replies = $$ '.reply', thread + replies.reverse() if delta is -1 + for reply in replies + rect = reply.getBoundingClientRect() + if delta is +1 and rect.top >= 0 or delta is -1 and rect.bottom <= d.body.clientHeight + reply.className = 'replyhl' + reply.tabIndex = 0 + reply.focus() + return Nav = # ◀ ▶ @@ -1013,8 +1008,6 @@ Nav = else Nav.scroll +1 - threads: [] - getThread: (full) -> Nav.threads = $$ '.thread:not([hidden])' for thread, i in Nav.threads @@ -1024,7 +1017,7 @@ Nav = if full return [thread, i, rect] return thread - return null + return $ 'form[name=delform]' scroll: (delta) -> [thread, i, rect] = Nav.getThread true