Hacker News - Highlight and navigate original poster's comments

Highlight original poster comments on Hackers News and navigate them with the keyboard

目前為 2015-02-26 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Hacker News - Highlight and navigate original poster's comments
// @description Highlight original poster comments on Hackers News and navigate them with the keyboard
// @namespace   valacar
// @include     https://news.ycombinator.com/item?id=*
// @version     0.1
// @grant       GM_addStyle
// ==/UserScript==

GM_addStyle(`
.originalPoster, .opPostCountInfo {
	background: #ff9;
	background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #ff9 100%);
}
`);

var ENABLE_KEYBOARD_NAVIGATION = true;

// ----------------------------------------------------------------------------

var posterUserName = document.querySelector('.subtext a').textContent;

if (posterUserName)
{
	var commentUserLinks = document.querySelectorAll('.comhead a');

	if (commentUserLinks)
	{
		var opPostCount = 0;
		for (var i = 0; i < commentUserLinks.length; i++)
		{
			var commentUserName = commentUserLinks[i].textContent;
			if (posterUserName === commentUserName)
			{
				opPostCount++;
				commentUserLinks[i].classList.add('originalPoster');
				commentUserLinks[i].id = 'op-post-' + opPostCount;

			}
		}
	}
}


if (opPostCount > 0) {
	var newSpan = document.createElement('span');
	newSpan.textContent = ' (' + opPostCount + ' by original poster)';
	newSpan.className = 'opPostCountInfo';

	if (ENABLE_KEYBOARD_NAVIGATION) {
		newSpan.setAttribute('title', "Use the left/right arrow keys (or 'n' / 'p') to scroll to OP comments.");
		newSpan.setAttribute('style', "cursor: help;");
	}

	var subText = document.querySelector('.subtext');

	subText.appendChild(newSpan);
}


// http://stackoverflow.com/questions/8922107/javascript-scrollintoview-middle-alignment
Element.prototype.documentOffsetTop = function () {
	return this.offsetTop + (this.offsetParent ? this.offsetParent.documentOffsetTop() : 0);
};

// TODO : get rid of ID's and use a custom attribute instead (?)
function ScrollToID(elID) {
	var top = document.getElementById(elID).documentOffsetTop() - (window.innerHeight * 0.1);
	window.scrollTo(0, top);
}



if (ENABLE_KEYBOARD_NAVIGATION) {
	var num = 0;

	window.addEventListener("keydown", function (event) {
		// Should do nothing if the key event was already consumed.
		if (event.defaultPrevented) {
			return;
		}

		// don't break alt-left and alt-right history navigation
		// and exit if textarea is in focus
		if (event.altKey || document.activeElement.tagName == 'TEXTAREA') {
			return;
		}


		switch (event.key) {
			case "n":
			case "ArrowRight":
			case "Right":
				if (num < opPostCount) {
					num++;
				}
			break;

			case "p":
			case "ArrowLeft":
			case "Left":
				if (num > 1) {
					num--;
				}
			break;

			default:
				return; // Quit when this doesn't handle the key event.
		}

		// Consume the event for suppressing "double action".
		event.preventDefault();

		//console.log('num = ' + num + ' focus = ' + document.activeElement.tagName);
		ScrollToID("op-post-" + num);

	}, true);

}