FT Ignorelist

An ignorelist for Fasttech forums

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        FT Ignorelist
// @namespace   ftignorelist
// @description An ignorelist for Fasttech forums
// @include     https://www.fasttech.com/forums/*
// @version     1.1
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_registerMenuCommand
// @run-at      document-end
// ==/UserScript==

// There's no compelling reason to enable this.
var use_localstorage = false

var default_settings = {
	'ignore': true,         // Hide posts from users on the ignore list
	'ignore_quotes': false, // Hide posts that quote users on the ignore list
	'insert_menu': true,    // Add a menu to the forum toolbar
	'ignorelist': [],       // The acutal ignore list
}

// Settings wrappers that automatically default missing values
function ftil_get(name, def) {
	if (use_localstorage)
		var item = localStorage.getItem('ftil_' + name)
	else
		var item = GM_getValue(name, null)

	if (item !== null)
		return JSON.parse(item)
	return default_settings[name]
}

function ftil_set(name, val) {
	if (use_localstorage)
		localStorage.setItem('ftil_' + name, JSON.stringify(val))
	else
		GM_setValue(name, JSON.stringify(val))
}

// Case-insensitive indexOf
function ftil_ci_indexof(a, n) {
	for (var i = 0; i < a.length; i++) {
		if (a[i].toLowerCase() === n.toLowerCase())
			return i
	}
	return -1
}

// GM Menu entries
function ftil_toggle_ignoring() {
	ftil_set('ignore', !ftil_get('ignore'))
	ftil_hide_posts()
}
GM_registerMenuCommand('FTIL: toggle ignoring', ftil_toggle_ignoring)

function ftil_toggle_quote_ignoring() {
	ftil_set('ignore_quotes', !ftil_get('ignore_quotes'))
	ftil_hide_posts()
}
GM_registerMenuCommand('FTIL: toggle quote ignoring', ftil_toggle_quote_ignoring)

function ftil_toggle_menu() {
	var val = !ftil_get('insert_menu')
	ftil_set('insert_menu', val)
	
	if (val) {
		ftil_add_popout()
		ftil_update_popout()
	} else {
		var menu = document.getElementById('Ignorelist')
		if (menu !== null)
			menu.remove()
		var popout = document.getElementById('IgnorelistPopout')
		if (popout !== null)
			popout.remove()
	}
}
GM_registerMenuCommand('FTIL: toggle menu', ftil_toggle_menu)

// Event handler for toggling ignored state of a user
function ftil_toggle_ignore_user() {
	var user = this.getAttribute('username')
	var ignorelist = ftil_get('ignorelist')

	var idx = ftil_ci_indexof(ignorelist, user)
	if (idx === -1)
		ignorelist.push(user)
	else
		ignorelist.splice(idx, 1)

	ftil_set('ignorelist', ignorelist)
	ftil_hide_posts()
	ftil_update_buttons()
	ftil_update_popout()
}

// Hide/unhide posts as the ignore list changes
function ftil_hide_posts() {
	var ignorelist = ftil_get('ignorelist')
	var ignore = ftil_get('ignore')
	var ignore_quotes = ftil_get('ignore_quotes')

	var quote_res = []
	if (ftil_get('ignore_quotes')) {
		for (var i in ignorelist)
			quote_res.push(new RegExp('\\b' + ignorelist[i] + ' wrote(</a>)?:?\n*<br>', 'i'))
	}

	var posts = document.getElementsByClassName('ForumThread')[0].getElementsByClassName('PostContent')
	for (var i = 0; i < posts.length; i++) {
		var display = ''
		var post = posts[i]
		if (ignore) {
			for (var j = 0; j < ignorelist.length; j++) {
				if (ignorelist[j].toLowerCase() === post.getAttribute('data-username').toLowerCase() ||
						(ignore_quotes && quote_res[j].test(post.innerHTML))) {
					display = 'none'
					break
				}
			}
		}

		var top_elem = post.parentElement.parentElement.parentElement
		top_elem.previousElementSibling.style.display = display
		top_elem.style.display = display
	}
}

// Add "ignore" links to the header above each post
function ftil_add_buttons() {
	var posts = document.getElementsByClassName('ForumThread')[0].getElementsByClassName('PostContent')
	for (var i = 0; i < posts.length; i++) {
		var top_elem = posts[i].parentElement.parentElement.parentElement
		var header = top_elem.previousElementSibling.firstElementChild.lastElementChild
		var new_a = document.createElement('a')
		var user = header.lastElementChild.getAttribute('data-username')
		new_a.setAttribute('href', 'javascript:void(0)')
		new_a.setAttribute('class', 'IgnoreButton')
		new_a.setAttribute('username', header.lastElementChild.getAttribute('data-username'))
		new_a.addEventListener('click', ftil_toggle_ignore_user)
		header.appendChild(new_a)
	}
}

// As needed, change "ignore" and "unignore" in post headers
function ftil_update_buttons() {
	var ignorelist = ftil_get('ignorelist')
	var buttons = document.getElementsByClassName('IgnoreButton')
	for (var i = 0; i < buttons.length; i++) {
		var button = buttons[i]
		if (ftil_ci_indexof(ignorelist, button.getAttribute('username')) === -1)
			button.innerHTML = '+ ignore'
		else
			button.innerHTML = '+ unignore'
	}
}

// Listeners for the popout menu
function ftil_cb_listen() {
	var v = this.getAttribute('var')
	ftil_set(v, this.checked)
	ftil_hide_posts()
}

function ftil_add_listen(k) {
	if (k.which !== 13)
			return true

	var user = this.value
	var ignorelist = ftil_get('ignorelist')
	if (user !== '' && ftil_ci_indexof(ignorelist, user) === -1) {
		ignorelist.push(user)
			ftil_set('ignorelist', ignorelist)
			ftil_hide_posts()
			ftil_update_buttons()
			ftil_update_popout()
	}

	this.value = ''

	k.stopPropagation()
	k.preventDefault()
	return false
}

// Insert a checkbox to control a setting
function ftil_checkbox(p, t, n) {
	var cb = document.createElement('input')
	cb.setAttribute('id', 'ftil_cb_' + n)
	cb.setAttribute('type', 'checkbox')
	cb.setAttribute('var', n)
	cb.checked = ftil_get(n)
	cb.addEventListener('click', ftil_cb_listen)
	p.appendChild(cb)

	var l = document.createElement('label')
	l.setAttribute('for', 'ftil_cb_' + n)
	l.innerHTML = t
	p.appendChild(l)
	p.appendChild(document.createElement('br'))
}

// Build the popout menu
// FIXME: this is just horrible
function ftil_add_popout() {
	if (!ftil_get('insert_menu'))
		return

	var bar = document.getElementsByClassName('ThreadCommandBar')[0]
	var span = document.createElement('span')
	span.setAttribute('id', 'Ignorelist')
	span.setAttribute('class', 'ThreadCommand')
	span.innerHTML = 'Ignore Users '
	bar.appendChild(span)

	var panel = document.createElement('div')
	panel.setAttribute('id', 'IgnorelistPopout')
	panel.setAttribute('class', 'PopoutPanel')
	panel.setAttribute('align', 'left')
	panel.setAttribute('style', 'position: absolute; height: auto; background-color: white; padding: 20px')
	bar.appendChild(panel)

	ftil_checkbox(panel, 'Hide posts', 'ignore')
	ftil_checkbox(panel, 'Hide quoting posts', 'ignore_quotes')

	var ltbl = document.createElement('table')
	panel.appendChild(ltbl)

	var ltby = document.createElement('tbody')
	ltby.setAttribute('id', 'ftil_tbody_ignorelist')
	ltbl.appendChild(ltby)

	var tb = document.createElement('input')
	tb.setAttribute('type', 'text')
	tb.setAttribute('placeholder', 'Add user...')
	tb.addEventListener('keydown', ftil_add_listen)
	panel.appendChild(tb)

	window.eval('PopoutMenu.init($("#Ignorelist"), $("#IgnorelistPopout"))')
}

// Add missing users to the popout
function ftil_list_add_missing(l, n) {
	for (var i = 0; i < l.children.length; i++) {
		if (n.toLowerCase() === l.children[i].lastElementChild.firstElementChild.getAttribute('username').toLowerCase())
			return
	}

	var tr = document.createElement('tr')
	tr.innerHTML = '<td>' + n + '</td><td><a href=javascript:void(0)><img src="/images/minus-button.png"></img></a></td>'
	var rem = tr.lastElementChild.firstElementChild
	rem.setAttribute('username', n)
	rem.addEventListener('click', ftil_toggle_ignore_user)
	l.appendChild(tr)
}

// Update the popout to reflect changes to the ignore list
function ftil_update_popout() {
	if (!ftil_get('insert_menu'))
		return

	var ignorelist = ftil_get('ignorelist')
	var list = document.getElementById('ftil_tbody_ignorelist')

	for (var i = 0; i < ignorelist.length; i++)
		ftil_list_add_missing(list, ignorelist[i])
	for (var i = list.children.length - 1; i >= 0; i--) {
		var child = list.children[i]
		if (ftil_ci_indexof(ignorelist, child.lastElementChild.firstElementChild.getAttribute('username')) === -1)
			child.remove()
	}
}

ftil_hide_posts()
ftil_add_buttons()
ftil_update_buttons()
ftil_add_popout()
ftil_update_popout()