noticeMF

highlight MetaFilter posts and comments containing user-specified text

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği yüklemek için Tampermonkey gibi bir uzantı yüklemeniz gerekir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// noticeMF.user.js
//
// Written by: Michael Devore
// Released to the public domain
//
// This is a Greasemonkey script.
// See http://www.greasespot.net/ for more information on Greasemonkey.
//
// ==UserScript==
// @name			noticeMF
// @namespace		http://www.devoresoftware.com/gm/noticeMF
// @description		highlight MetaFilter posts and comments containing user-specified text
// @match			https://*.metafilter.com/*
// @match			http://*.metafilter.com/*
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @grant GM_setValue 
// @grant GM_getValue 
// @run-at document-end
// @version 1.0
// ==/UserScript==
//

"use strict";

var theBorderWidth = "5px";

GM_addStyle('#div_configureHighlightBox{\
	position: fixed;\
	left: 50%;\
	margin-left: -11em;\
	bottom: 5px;\
	color: black;\
	background-color: white;\
	border: 2px green solid;\
	padding: 2px;\
	opacity: 0.95;\
}');
GM_addStyle('.textarea_configureHighlightBox{\
	width: 25em;\
	height: 8.34em;\
	margin-left: 5px;\
	margin-right: 5px;\
	border: 2px black solid;\
	color: black;\
	background-color: white;\
	white-space: pre;\
	word-wrap: normal;\
	overflow-x: scroll;\
}');
GM_addStyle('.header_configureHighlightBox, .text_configureHighlightBox{\
	text-align: center;\
}');
GM_addStyle('.button_configureHighlightBox{\
	display:block;\
	margin: 0 auto;\
}');

var aquaText = "aqua";
var blackText = "black";
var limeText = "lime";
var orangeText = "orange";
var pinkText = "pink";
var redText = "red";
var yellowText = "yellow";
var noneText = "none";
var blockText = "block";
var highlightList = new Array();
var highlightColor = redText;
 
function onLoaded()
{
	loadConfiguration();
	buildConfigureBox();
	performHighlight();
}

function loadConfiguration()
{
	var workString = GM_getValue("highlightList", "");
	if (workString.length > 0)
	{
		var workArray = workString.split(',');
		highlightList = [];
		for (var loop = 0; loop < workArray.length; loop++)
		{
			highlightList.push(decodeURIComponent(workArray[loop]));
		}
	}

	highlightColor = GM_getValue("highlightColor", redText);
}

function saveConfiguration()
{
	var div = $("#div_configureHighlightBox");
	div.style.display = noneText;

	var textArea = $("#highlightTextArea");
	var text;
	if (!textArea || !textArea.value)
	{
		text = "";
	}
	else
	{
		text = textArea.value.trim();
	}
	var highlightListArray = text.split("\n");

	highlightList = [];
	var tempArray = [];
	for (var loop = 0; loop < highlightListArray.length; loop++)
	{
		highlightList.push(highlightListArray[loop]);
		tempArray.push(encodeURIComponent(highlightListArray[loop]));
	}
	var tempString = tempArray.join(",");
	GM_setValue("highlightList", tempString);

	GM_setValue("highlightColor", highlightColor);
	location.reload();
}

function performHighlight()
{
	if (highlightList.length < 1)
	{
		// no filters
		return;
	}

	var xpath = "//DIV/SPAN[starts-with(text(),'posted by') and contains(@class, 'smallcopy')]";
	var postNodes = document.evaluate(
		xpath,
		document,
		null,
		XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
		null
	);
	var total = postNodes.snapshotLength;
	for (var i = 0; i < total; i++)
	{
		// not much validation here, cuts performance overhead by avoiding extra tests against the nodes
		// tighten it down later if it conflicts with other add-ons or Metafilter bling
		var userSpan = postNodes.snapshotItem(i);
		var copyDiv = userSpan.parentNode;

		// check for match in text
		var highlightPost = false;
		var text = copyDiv.textContent;
		for (var j = 0; j < highlightList.length; j++)
		{
			var textPattern = new RegExp("\\b"+highlightList[j]+"\\b","i");
			if (text.match(textPattern))
			{
				highlightPost = true;
				break;
			}
		}
		if (highlightPost)
		{
			copyDiv.style.border = theBorderWidth+" "+highlightColor+" solid";
		}
	}
}

function buildConfigureBox()
{
	var mainDiv = document.createElement('div');
	mainDiv.id = "div_configureHighlightBox";
	var highlightTextArea = document.createElement('textarea');
	highlightTextArea.id = "highlightTextArea";
	highlightTextArea.className = "textarea_configureHighlightBox";
	var highlightListString = highlightList.join("\n");
	highlightTextArea.value = highlightListString;

	var h2 = document.createElement('h2');
	h2.className = "header_configureHighlightBox";
	h2.appendChild(document.createTextNode('Configure noticeMF'));
	mainDiv.appendChild(h2);

	var minorDiv = document.createElement('div');
	minorDiv.appendChild(document.createElement('br'));
	minorDiv.appendChild(document.createTextNode('Box outline a post or comment containing text'));
	minorDiv.appendChild(document.createElement('br'));
	minorDiv.appendChild(document.createTextNode('(one entry per line)'));
	minorDiv.appendChild(document.createElement('br'));
	minorDiv.appendChild(highlightTextArea);

	minorDiv.appendChild(document.createElement('br'));
	minorDiv.appendChild(document.createElement('br'));
	minorDiv.appendChild(document.createTextNode('Outline box color'));
	minorDiv.appendChild(document.createElement('br'));
	minorDiv.className = "text_configureHighlightBox";

	var select = document.createElement("select");
	for (var i = 0; i < 7; i++)
	{
		var option = document.createElement("option");
		var which;
		switch(i)
		{
			case 0:
				which = aquaText;
				break;
			case 1:
				which = blackText;
				break;
			case 2:
				which = limeText;
				break;
			case 3:
				which = orangeText;
				break;
			case 4:
				which = pinkText;
				break;
			case 5:
				which = redText;
				break;
			case 6:
			default:
				which = yellowText;
				break;
		}
		if (highlightColor == which)
		{
			option.selected = true;
		}
		else
		{
			option.selected = false;
		}
		option.id = "option_"+which;
		option.value = which;
		option.appendChild(document.createTextNode(which));
		select.appendChild(option);
	}
	minorDiv.appendChild(select);
	minorDiv.appendChild(document.createElement('br'));
	select.addEventListener('change', newColor, true);
	mainDiv.appendChild(minorDiv);

	mainDiv.appendChild(document.createElement('br'));
	mainDiv.appendChild(document.createElement('br'));
	var saveNode = document.createElement("button");
	saveNode.appendChild(document.createTextNode("Save"));
	saveNode.className = "button_configureHighlightBox";
	saveNode.addEventListener("click", saveConfiguration, true);
	mainDiv.appendChild(saveNode);

	mainDiv.style.display = noneText;
	document.getElementsByTagName('body')[0].appendChild(mainDiv);
}

function newColor()
{
	highlightColor = this.options[this.selectedIndex].value;
}

function showConfigure()
{
	loadConfiguration();
	var div = $("#div_configureHighlightBox");
	div.style.display = blockText;
}

function $(aSelector, aNode)
{
	return (aNode || document).querySelector(aSelector);
}

document.addEventListener('DOMContentLoaded',onLoaded,true);
GM_registerMenuCommand("Configure noticeMF", showConfigure, "n");