Shoutbox Linkify

Links certain text (e.g. /profile/pet/42) in the shoutbox.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Shoutbox Linkify
// @namespace    fortytwo
// @homepageURL	 https://greasyfork.org/en/users/14247-fortytwo
// @supportURL	 http://games-fortytwo.tumblr.com/tagged/shoutbox%20linkify
// @version      2.1
// @description  Links certain text (e.g. /profile/pet/42) in the shoutbox.
// @author       fortytwo
// @match        http://www.clanheart.com/*
// @grant        GM_getValue
// @grant		 GM_setValue
// @noframes
// @compatible	 chrome
// @compatible	 firefox
// ==/UserScript==
/***
	NOTICE: YOU ARE AGREEING THAT ANY USE OF THE FOLLOWING SCRIPT IS AT
	YOUR OWN RISK. I DO NOT MAKE ANY GUARANTEES THE SCRIPT WILL WORK, NOR 
	WILL I HOLD MYSELF ACCOUNTABLE FOR DAMAGE TO YOUR DEVICE.

	WHILE THE SCRIPT IS UNLIKELY TO CAUSE ANY HARM, AS WITH ALL TECHNICAL
	COMPONENTS, BUGS AND GLITCHES CAN HAPPEN.

	IF THE SCRIPT ISN'T WORKING FOR YOU, FEEL FREE TO SEND ME A MESSAGE: http://games-fortytwo.tumblr.com/
***/
(function(){
	//No shoutbox, then don't run.
	if(!document.getElementById('shoutbox-panel')){
		return;
	}

	var data = GM_getValue('shoutbox-linkify-data', {
		regexp:		'',
		text_comma: ''
	});

	//console.log(data);

	var replaceables =[
		//profile/pet/42
		{ match: /\/?profile\/pet\/([0-9]+)\/?/gim, content: "<a href='http://clanheart.com/profile/pet/$1'>pet #$1</a> "},
		//forums/topic/42?page=5
		{ match: /\/?forums\/topic\/([0-9]+)\/?\?page=([0-9]+)/gim, content: "<a href='http://clanheart.com/forums/topic/$1?page=$2'>topic #$1?page=$2</a> "},
		//forums/topic/42
		{ match: /\/?forums\/topic\/([0-9]+)\/?/gim, content: "<a href='http://clanheart.com/forums/topic/$1'>topic #$1</a> "},
		//trading/make_offer/42
		{ match: /\/?trading\/make_offer\/([0-9]+)\/?/gim, content: "<a href='http://clanheart.com/trading/make_offer/$1'>offer on pet #$1</a> "},
		//settings/changeClan, settings/whatever
		{ match: /\/?settings\/([0-9a-z]+)\/?/gim, content: "<a href='http://clanheart.com/settings/$1'>settings: #$1</a> "}
	];
	
	//Add highlights, if there are any by piping them together
	if(data.regexp){
		//Use the one we saved as regexp safe (escaped)
		var arr = JSON.parse(data.regexp);

		replaceables.push({
			match: new RegExp("([\\s|,|\.|@|!|:])("+arr.join("|")+")([\\s|,|\.|@|!|:])", "gim"),
			content: "$1<mark class='bg-danger'>$2</mark>$3"
		});
	}

	//for testing
	//console.log(replaceables);
	//console.log(linkify("@42 forty lfkmfk.nf \n4242\nlorem /profile/pet/42: no fkfnjk /profile/pet/42 42: hello lorem ipsum \n` 42 "));

	function linkify(text){
		for(var i = 0; i < replaceables.length; ++i){
			text = text.replace(replaceables[i].match, replaceables[i].content);
		}
		return text;
	};

	function magic(){
		var posts = document.getElementById('shoutbox-panel').getElementsByClassName('col-md-10');
		for(var i = 0; i < posts.length; ++i){
			//Fetch data. We want to get the string itself, manipulate it
			//and then add time and user link back in
			var post = posts[i];
			var e_userlink = post.getElementsByClassName('sb-link')[0];
			var e_time = post.getElementsByClassName("shoutbox-date")[0];

			//Collect data
			var a = {
				href: e_userlink.href,
				html: e_userlink.innerHTML
			};

			var time = e_time.innerHTML;

			//Eliminate all but the text content of our post
			for(var j = 0; j < post.childNodes.length; ++j){
				if(post.childNodes[j].nodeType != 3){
					post.removeChild(post.childNodes[j--]);
				}
			}

			//Add a ' ' otherwise our regexp doesn't match at the end or start? Bluh
			var text = linkify(" "+post.innerHTML.trim()+" ");

			//Form content back as it was with our new content
			post.innerHTML = [
				"<a href='"+a.href+"' class='sb-link'>"+a.html+"</a>",
				"<br>",
				text,
				"<div class='shoutbox-date'>"+time+"</div>"
			].join("");
		}
	};

	//Make sure to monitor changes to the shoutbox
	var sbObserver = new MutationObserver(function(mutations){
		for(var i = 0; i < mutations.length; ++i){
			var mutation = mutations[i];

			if(mutation.addedNodes.length > 0){
				magic();
			}
		}
	}).observe(document.getElementById('shoutbox-panel'), { childList: true });
	
	//Initial state
	magic();
	
	
	/* Settings Page */
	if(window.location.pathname === "/settings"){
		//Find the form
		var forms = document.forms,
			myForm;

		for(var i = 0; i < forms.length; ++i){
			var form = forms[i];
			if(form.action === "http://www.clanheart.com/settings/update"){
				myForm = form;
				break;
			}
		}

		//Exit if no form could be found
		if(!myForm){
			return;
		}
		
		//Get on with it
		var newNode = document.createElement('div');
		newNode.className = "form-group";
		newNode.innerHTML = [
			'<label for="name-in" class="col-md-3 label-heading">Shoutbox Linkify</label>',
			'<div class="col-md-12">',
				'<input type="text" id="sb_linkify_highlights" class="form-control" value="'+data.text_comma+'" />',
				'<span class="help-block">Pick words to highlight on in the shoutbox. Separate by ", ". Changes will take effect when you click Update.</span>',
			'</div>'
		].join("");

		//Insert the content
		myForm.insertBefore(newNode, myForm.getElementsByTagName('input')['s']);

		//Add onchange handler
		document.getElementById('sb_linkify_highlights').onchange = function(){
			//remove ws and stuff
			var words = this.value
				.split(", ")
				.map(function(value){
					return value.trim();
				})
				//clean it up
				.filter(function(value){
					return value.length > 0;
				});

			if(words.length){
				//We need to escape it to our regex
				var words_regexp = JSON.stringify(words.map(function(value){
					return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
				}));
			}
			else{
				var words_regexp = '';
			}
			GM_setValue("shoutbox-linkify-data", {
				regexp:		words_regexp,
				text_comma:	words.join(", ")
			});
		};
	}
})();