Skip to content

Instantly share code, notes, and snippets.

@justinjc
Last active January 23, 2019 20:03
Show Gist options
  • Save justinjc/6d33efd84d892202f8e0b5d5b47a3935 to your computer and use it in GitHub Desktop.
Save justinjc/6d33efd84d892202f8e0b5d5b47a3935 to your computer and use it in GitHub Desktop.
// ==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