您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
further enhancements for Kuro5hin.org
当前为
// ==UserScript== // @name BlastarBegoner ][+ // @namespace // @description further enhancements for Kuro5hin.org // @include http://www.kuro5hin.org/* // @include https://www.kuro5hin.org/* // @version 0.5 // ==/UserScript== var ShitList = new Object(); // start config /* * set to false to also kill replies to killed comments. */ var Orphans = true; /* * if you wish to ignore a user, add them, like below. * note this is case sensitive. */ ShitList['Edmund Blackadder'] = true; ShitList['Skeletor'] = true; ShitList['Thomas Hard'] = true; ShitList['Riddick'] = true; ShitList['Atari 2600'] = true; ShitList['Horsecock Sodomy'] = true; // end config var xmlRequest = new XMLHttpRequest(); var forms = document.forms; var rating_re = /^rating_(\d+)$/; var user_re = /\/user\/uid:(\d+)$/; var diary_re = /\/user\/([a-zA-Z0-9% ]+)\/diary$/; // check if there's anybody on the shit list. var DoSL = false; for (var i in ShitList) { DoSL = true; break; } //utility functions to make life easier. // creates a new option element. // GreaseMonkey doesn't support new Option() / select.add() function newOption(name, value) { var x = document.createElement('option'); x.value = value; x.appendChild(document.createTextNode(name)); return x; } // find a specific parent element for a tag. // k5 is chock full of nested tables and such. function outerElement(node, tag, count) { if (count == 0) return null; if (node == null) return null; if (node.nodeType == 1 && node.tagName == tag) { if (--count == 0) return node; } node = node.parentNode; return node ? outerElement(node, tag, count) : null; } // returns the first element or null if none. // function firstChildElement(node) { if (node == null) return null; node = node.firstChild; while (node) { if (node.nodeType == 1) return node; } return null; } // gets the next element (tag), ignoring text, cdata, comments, etc. function nextElement(element) { while (element = element.nextSibling) { if (element.nodeType == 1) return element; } return null; } // gets the previous element (tag), ignoring text, cdata, comments, etc. function previousElement(element) { while (element = element.previousSibling) { if (element.nodeType == 1) return element; } return null; } // copys elements from a NodeList (which is live) to an array (which is not) function nodeArray(nodeList) { var array = new Array(nodeList.length); for (var i = 0; i < nodeList.length; i++) array[i] = nodeList[i]; return array; } // onclick, onsubmit callbacks. // replacement comment rater. This uses xmlhttprequest and is done asynchronously. function rateComments(event) { event.preventDefault(); var form = event.target; var post = ''; var inc = new Object(); // build up the post data. for (var j = 0; j < form.elements.length; j++) { var e = form.elements[j]; if (e.name != '') { if (inc[e.name]) continue; inc[e.name] = true; post = post + '&' + encodeURIComponent(e.name) + '=' + encodeURIComponent(e.value); } } post = post.substr(1); //alert(post); xmlRequest.open('POST', form.action, true); xmlRequest.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); xmlRequest.onreadystatechange = function() { if (xmlRequest.readyState == 4) { //alert('done'); } } xmlRequest.send(post); } // set all comment ratings to the specified rating. function bitchSlap(event) { event.preventDefault(); var form = event.target.form; var value = document.getElementById('__select').value; for (var j = 0; j < form.elements.length; j++) { var e = form.elements[j]; if (e.type == 'select-one') { if (e.name.match(rating_re)) { e.value = value; } } } } // show/hide comment replies. replies are placed in a <dl><dt> after the comment. function showHide(event) { event.preventDefault(); var target = event.target; var hide = target.firstChild.data == 'Hide Replies'; target.firstChild.data = hide ? 'Show Replies' : 'Hide Replies'; var comment = outerElement(target, 'TABLE', 2); if (comment) { comment = nextElement(comment); if (comment.tagName == 'DL' || comment.tagName == 'dl') { comment.style.visibility = hide ? 'collapse' : 'visible'; } } } // remove comments from people on the shitlist. function killComments(form) { var delta = false; var links = nodeArray(form.getElementsByTagName('a')); for (var j = 0; j < links.length; j++) { var link = links[j]; //if (link.href.indexOf('uid') != -1) // alert(link.href + ' ' + link.firstChild.data); if (!link.href.match(user_re)) continue; var user = link.firstChild.data; if (!ShitList[user]) continue; var comment = outerElement(link, 'TABLE', 3); if (comment) { if (Orphans == false) { var temp = nextElement(comment); if (temp && temp.tagName == 'DL') temp.parentNode.removeChild(temp); } comment.parentNode.removeChild(comment); delta = true; } } if (delta) { // now go through and kill any blank indentations // (<dl><dt></dt><dd></dd></dl>) var dls = nodeArray(form.getElementsByTagName('dl')); for (var j = 0; j < dls.length; j++) { var dl = dls[j]; var kill = true; var x = dl.firstChild; while(x && kill) { if (firstChildElement(x)) kill = false; x = x.nextSibling(); } if (kill) { dl.parentNode.removeChild(dl); } } } } // remove diary entries from people on the shitlist function killDiaryEntries() { var links = nodeArray(document.body.getElementsByTagName('a')); for (var j = 0; j < links.length; j++) { var match; var link = links[j]; if (match = link.href.match(diary_re)) { var name = match[1]; // convert %20 to ' ' name = decodeURIComponent(name); if (!ShitList[name]) continue; var p = outerElement(link, 'TABLE', 1); if (p) p.parentNode.removeChild(p); } } } // remove diary sidebar entries from people on the shitlist function killDiarySidebars() { var links = nodeArray(document.body.getElementsByTagName('a')); for (var j = 0; j < links.length; j++) { var match; var link = links[j]; if (match = link.href.match(diary_re)) { var name = match[1]; // convert %20 to ' ' name = decodeURIComponent(name); if (!ShitList[name]) continue; var p = outerElement(link, 'P', 1); if (p) p.parentNode.removeChild(p); } } } // add a link to show/hide child comments. function addShowHide(form) { // I wanted to base this on the "rate" button, but that fails // for your own comments.... sigh... var links = nodeArray(form.getElementsByTagName('a')); for (var j = 0; j < links.length; j++) { var link = links[j]; if (link.href.indexOf('/post#here') == -1) continue; var comment = outerElement(link, 'TABLE', 2); // check for any replies... var temp = nextElement(comment); if (temp && temp.tagName == 'DL') { var parent = link.parentNode; parent.insertBefore(document.createTextNode(' '), link); var newlink = parent.insertBefore(document.createElement('a'), link); newlink.href = '#'; newlink.appendChild(document.createTextNode('Hide Replies')); newlink.addEventListener('click', showHide, true); parent.insertBefore(document.createTextNode(' | '), link); } } } if (window.location.href.indexOf('/story/') > 0 || window.location.href.indexOf('/comments/') > 0 ) { for (var i = 0; i < forms.length; i++) { var form = forms[i]; if (form.name == 'rate') { // 1. posting will be done via xmlhttprequest. form.addEventListener('submit', rateComments, true); // 4 kills comments from users on the shit list. // this will not kill any replies, however, // which it probably should do as well. if (DoSL) killComments(form); // - - - - - - - - // 2a add a reset button // 2b. add dhtml button to rate all comments. var div = document.createElement('div'); var x; div.style.textAlign = 'center'; form.insertBefore(div, form.firstChild); x = div.appendChild(document.createElement('input')); x.type = 'reset'; x.value = 'Reset Ratings'; div.appendChild(document.createTextNode(' ')); x = div.appendChild(document.createElement('select')); x.id = '__select'; // greasemonkey can't use the select.add() method. x.appendChild(newOption('None', 'none')); x.appendChild(newOption('Hide', 0)); x.appendChild(newOption('Discourage', 1)); x.appendChild(newOption('Neutral', 2)); x.appendChild(newOption('Encourage', 3)); div.appendChild(document.createTextNode(' ')); x = div.appendChild(document.createElement('input')); x.type = 'button'; x.value = 'Set Ratings'; x.addEventListener('click', bitchSlap, true); // - - - - - - - - // 3. add show/hide replies link addShowHide(form); } } }// /story/ page else { // kill off diary pages from people in the shitlist if (DoSL) if (window.location.href.indexOf('/section/') > 0) killDiaryEntries(); else killDiarySidebars(); } // fix up indentation a bit. GM_addStyle('dd { padding-left: 0px; margin-left: 0px;}'); GM_addStyle('dl { padding-left: 1.5em; margin-left: 0px;}');