Last active
January 23, 2019 20:03
-
-
Save justinjc/6d33efd84d892202f8e0b5d5b47a3935 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 Prev/Next Github comment | |
// @namespace justinjc | |
// @description Userscript that adds prev/next comment hotkeys for Github. | |
// @include https://github.com* | |
// @version 0.1 | |
// @author Justin Chan | |
// @copyright 2019 Justin Chan | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
var modifier = "Control"; | |
var prevKeyCode = 74; // k | |
var nextKeyCode = 75; // j | |
// Modifier to align the top of a comment at what height on the screen | |
// 0 = top of screen; 1 = bottom of screen | |
var screenOffset = 0.3; | |
function nextCommentIdx(comments, currY) { | |
var center = currY + scrollOffset() | |
for (var i = 0; i < comments.length; i++) { | |
var commentY = posY(comments[i]); | |
if (commentY == currY || commentY <= center) { | |
continue; | |
} | |
return i; | |
} | |
return -1; | |
} | |
function prevCommentIdx(comments, currY) { | |
var center = currY + scrollOffset() | |
for (var i = comments.length - 1; i >= 0; i--) { | |
var commentY = posY(comments[i]); | |
if (commentY == currY || commentY >= center) { | |
continue; | |
} | |
return i; | |
} | |
return -1; | |
} | |
function posY(ele) { | |
var box = ele.getBoundingClientRect(); | |
var body = document.body; | |
var docEl = document.documentElement; | |
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; | |
var clientTop = docEl.clientTop || body.clientTop || 0; | |
var top = box.top + scrollTop - clientTop; | |
return Math.round(top); | |
} | |
function scrolled(origY) { | |
return origY != window.pageYOffset; | |
} | |
function scrollOffset() { | |
return Math.floor(window.innerHeight * screenOffset); | |
} | |
function gotoComment(e) { | |
var comments = document.getElementsByClassName("js-resolvable-thread-contents"); | |
var origY = window.pageYOffset; | |
if (e.getModifierState(modifier) && e.keyCode === prevKeyCode) { | |
nextComment(comments, origY) | |
} | |
if (e.getModifierState(modifier) && e.keyCode === nextKeyCode) { | |
prevComment(comments, origY) | |
} | |
} | |
function nextComment(comments, origY) { | |
var idx = nextCommentIdx(comments, origY); | |
if (idx == -1) { | |
return; | |
} | |
for (var i = idx; i < comments.length; i++) { | |
comments[i].scrollIntoView(); | |
if (scrolled(origY)) { | |
window.scrollBy(0, -scrollOffset()) | |
return; | |
} | |
} | |
} | |
function prevComment(comments, origY) { | |
var idx = prevCommentIdx(comments, origY); | |
if (idx == -1) { | |
return; | |
} | |
for (var i = idx; i >= 0; i--) { | |
comments[i].scrollIntoView(); | |
if (scrolled(origY)) { | |
window.scrollBy(0, -scrollOffset()) | |
return; | |
} | |
} | |
} | |
document.addEventListener('keydown', gotoComment); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment