您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
killfile script, re-rebooted
// diediedead.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 diediedead // @namespace http://www.devoresoftware.com/gm/dddead // @description killfile script, re-rebooted // @match https://*.metafilter.com/* // @match http://*.metafilter.com/* // @grant GM_addStyle // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @run-at document-start // @version 3.4 // ==/UserScript== // "use strict"; GM_addStyle('body{display:none;}'); GM_addStyle('#div_configureBox{\ position: fixed;\ left: 50%;\ margin-left: -11em;\ // top: 5px;\ bottom: 5px;\ color: black;\ background-color: white;\ border: 2px green solid;\ padding: 2px;\ opacity: 0.95;\ }'); GM_addStyle('.textarea_configureBox{\ width: 20em;\ height: 5.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_configureBox{\ text-align: center;\ }'); GM_addStyle('.button_configureBox{\ display:block;\ margin: 0 auto;\ }'); var filterActionEnum = { NONE: "none", POSTSANDCOMMENTS: "postsandcomments", POSTSONLY: "postsonly", COMMENTSONLY: "commentsonly" }; Object.freeze(filterActionEnum); var filterAction = filterActionEnum.POSTSANDCOMMENTS; var noActiveSelectionText = "<no active selection>"; var showAllContextText = "Show all content"; var filterPostsAndComments = "Filter posts & comments"; var filterPostsOnly = "Filter posts only"; var filterCommentsOnly = "Filter comments only"; var configureFilters = "Configure filters"; var filterForUser = "Filter for user "; var filterForText = "Filter for text "; var filterForSite = "Filter for site "; var noneText = "none"; var blockText = "block"; var userFilters = new Array(); var textFilters = new Array(); var siteFilters = new Array(); function onLoaded() { buildContextMenu(); buildConfigureBox(); loadConfiguration(); performFiltering(); GM_addStyle('body{display:block;}'); } function contextClick(e) { var menuitem = e.target; var label = menuitem.label; if (label == configureFilters) { showConfigure(); return; } var reload = false; if (label == showAllContextText) { filterAction = filterActionEnum.NONE; GM_setValue("filterAction", showAllContextText); var menuitem = $("#show_all_content"); menuitem.checked = true; reload = true; } else if (label == filterPostsAndComments) { filterAction = filterActionEnum.POSTSANDCOMMENTS; GM_setValue("filterAction", filterPostsAndComments); menuitem = $("#filter_posts_and_comments"); menuitem.checked = true; reload = true; } else if (label == filterPostsOnly) { filterAction = filterActionEnum.POSTSONLY; GM_setValue("filterAction", filterPostsOnly); menuitem = $("#filter_posts_only"); menuitem.checked = true; reload = true; } else if (label == filterCommentsOnly) { filterAction = filterActionEnum.COMMENTSONLY; GM_setValue("filterAction", filterCommentsOnly); menuitem = $("#filter_comments_only"); menuitem.checked = true; reload = true; } if (!reload) { var workString = label.slice(0, filterForUser.length); if (workString == filterForUser) { workString = label.slice(filterForUser.length) addUserToFilter(workString); var tempString = GM_getValue("filteredUsers", ""); if (tempString.length > 0) { tempString += ","; } workString.trim(); tempString += encodeURIComponent(workString); GM_setValue("filteredUsers", tempString); reload = true; } } if (!reload) { workString = label.slice(0, filterForText.length); if (workString == filterForText) { workString = label.slice(filterForText.length) addTextToFilter(workString); var tempString = GM_getValue("filteredText", ""); if (tempString.length > 0) { tempString += ","; } workString.trim(); tempString += encodeURIComponent(workString); GM_setValue("filteredText", tempString); reload = true; } } if (!reload) { workString = label.slice(0, filterForSite.length); if (workString == filterForSite) { workString = label.slice(filterForSite.length) addSiteToFilter(workString); var tempString = GM_getValue("filteredSites", ""); if (tempString.length > 0) { tempString += ","; } workString.trim(); tempString += encodeURIComponent(workString); GM_setValue("filteredSites", tempString); reload = true; } } if (reload) { location.reload(); return; } } function addUserToFilter(user) { userFilters.push(user); } function addTextToFilter(text) { textFilters.push(text); } function addSiteToFilter(site) { siteFilters.push(site); } function loadConfiguration() { var workString = GM_getValue("filteredUsers", ""); if (workString.length > 0) { var workArray = workString.split(','); userFilters = []; for (var loop = 0; loop < workArray.length; loop++) { userFilters.push(decodeURIComponent(workArray[loop])); } var userFiltersString = userFilters.join("\n"); var textArea = $("#userTextArea"); textArea.value = userFiltersString; } workString = GM_getValue("filteredText", ""); if (workString.length > 0) { var workArray = workString.split(','); textFilters = []; for (var loop = 0; loop < workArray.length; loop++) { textFilters.push(decodeURIComponent(workArray[loop])); } var textFiltersString = textFilters.join("\n"); var textArea = $("#contentTextArea"); textArea.value = textFiltersString; } workString = GM_getValue("filteredSites", ""); if (workString.length > 0) { var workArray = workString.split(','); siteFilters = []; for (var loop = 0; loop < workArray.length; loop++) { siteFilters.push(decodeURIComponent(workArray[loop])); } var siteFiltersString = siteFilters.join("\n"); var textArea = $("#siteTextArea"); textArea.value = siteFiltersString; } var menuitem = $("#show_all_content"); menuitem.checked = false; menuitem = $("#filter_posts_only"); menuitem.checked = false; menuitem = $("#filter_comments_only"); menuitem.checked = false; menuitem = $("#filter_posts_and_comments"); menuitem.checked = false; workString = GM_getValue("filterAction", filterPostsAndComments); if (workString == showAllContextText) { menuitem = $("#show_all_content"); menuitem.checked = true; filterAction = filterActionEnum.NONE; } else if (workString == filterPostsOnly) { menuitem = $("#filter_posts_only"); menuitem.checked = true; filterAction = filterActionEnum.POSTSONLY; } else if (workString == filterCommentsOnly) { menuitem = $("#filter_comments_only"); menuitem.checked = true; filterAction = filterActionEnum.COMMENTSONLY; } else { menuitem = $("#filter_posts_and_comments"); menuitem.checked = true; filterAction = filterActionEnum.POSTSANDCOMMENTS; } var radio = $("#radio_ShowAll"); if (filterAction == filterActionEnum.NONE) { radio.checked = true; } else { radio.checked = false; } radio = $("#radio_CommentsAndPosts"); if (filterAction == filterActionEnum.POSTSANDCOMMENTS) { radio.checked = true; } else { radio.checked = false; } radio = $("#radio_PostsOnly"); if (filterAction == filterActionEnum.POSTSONLY) { radio.checked = true; } else { radio.checked = false; } radio = $("#radio_CommentsOnly"); if (filterAction == filterActionEnum.COMMENTSONLY) { radio.checked = true; } else { radio.checked = false; } } function saveConfiguration() { var div = $("#div_configureBox"); div.style.display = noneText; var textArea = $("#userTextArea"); var text; if (!textArea || !textArea.value) { text = ""; } else { text = textArea.value.trim(); } var userFiltersArray = text.split("\n"); textArea = $("#contentTextArea"); if (!textArea || !textArea.value) { text = ""; } else { text = textArea.value.trim(); } var textFiltersArray = text.split("\n"); textArea = $("#siteTextArea"); if (!textArea || !textArea.value) { text = ""; } else { text = textArea.value.trim(); } var siteFiltersArray = text.split("\n"); userFilters = []; var tempArray = []; for (var loop = 0; loop < userFiltersArray.length; loop++) { userFilters.push(userFiltersArray[loop]); tempArray.push(encodeURIComponent(userFiltersArray[loop])); } var tempString = tempArray.join(","); GM_setValue("filteredUsers", tempString); textFilters = []; tempArray = []; for (var loop = 0; loop < textFiltersArray.length; loop++) { textFilters.push(textFiltersArray[loop]); tempArray.push(encodeURIComponent(textFiltersArray[loop])); } var tempString = tempArray.join(","); GM_setValue("filteredText", tempString); siteFilters = []; tempArray = []; for (var loop = 0; loop < siteFiltersArray.length; loop++) { siteFilters.push(siteFiltersArray[loop]); tempArray.push(encodeURIComponent(siteFiltersArray[loop])); } var tempString = tempArray.join(","); GM_setValue("filteredSites", tempString); var menuitem1 = $("#radio_ShowAll"); var menuitem2 = $("#radio_PostsOnly"); var menuitem3 = $("#radio_CommentsOnly"); if (menuitem1.checked) { filterAction = filterActionEnum.NONE; GM_setValue("filterAction", showAllContextText); } else if (menuitem2.checked) { filterAction = filterActionEnum.POSTSONLY; GM_setValue("filterAction", filterPostsOnly); } else if (menuitem3.checked) { filterAction = filterActionEnum.COMMENTSONLY; GM_setValue("filterAction", filterCommentsOnly); } else { filterAction = filterActionEnum.POSTSANDCOMMENTS; GM_setValue("filterAction", filterPostsAndComments); } location.reload(); } function performFiltering() { if (filterAction == filterActionEnum.NONE) { // don't filter return; } if (userFilters.length < 1 && textFilters.length < 1 && siteFilters.length < 1) { // no filters return; } // var xpath = "//DIV/SPAN[starts-with(text(),'posted by') and (@class='smallcopy' or @class='smallcopy byline')]"; 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; var titleDiv = copyDiv.previousSibling.previousSibling; // music uses H1 instead of DIV, whatever if (titleDiv.nodeName != "DIV" && titleDiv.nodeName != "H1" && titleDiv.nodeName != "H2") { titleDiv = null; } if (!titleDiv && filterAction == filterActionEnum.POSTSONLY) { // not a post (assumed comment), and only filtering posts continue; } if (titleDiv && filterAction == filterActionEnum.COMMENTSONLY) { // post, and only filtering comments continue; } var currentNode = userSpan.firstChild; var found = false; var userName; while (currentNode && !found) { if (currentNode.nodeName === "A") { var href_value = currentNode.getAttribute('href'); if (href_value.match(/\/user\/\d/)) { var childNode = currentNode.firstChild; while (childNode) { if (childNode.nodeName === '#text') { userName = childNode.nodeValue; found = true; break; } childNode = childNode.nextSibling; } } } currentNode = currentNode.nextSibling; } if (!userName) { // even if we're not filtering by user name, if there isn't one associated with a post, it's not a good target continue; } var postHidden = false; // check user name, applies to posts and comments for (var j = 0; j < userFilters.length; j++) { if (userName == userFilters[j]) { postHidden = true; break; } } if (filterAction == filterActionEnum.POSTSONLY || (filterAction == filterActionEnum.POSTSANDCOMMENTS && titleDiv)) { // we know this is a post title, not a comment, and it should be subject to filtering // check for link currentNode = titleDiv.firstChild; found = false; var link = null; while (currentNode && !found) { if (currentNode.nodeName === "A") { link = currentNode.getAttribute('href'); found = true; break; } currentNode = currentNode.nextSibling; } for (var j = 0; link && j < siteFilters.length; j++) { var sitePattern = new RegExp("^(https?://)?"+siteFilters[j]); if (link.match(sitePattern)) { postHidden = true; break; } } if (!postHidden) { // check for text var text = titleDiv.textContent; for (var j = 0; j < textFilters.length; j++) { var textPattern = new RegExp("\\b"+textFilters[j]+"\\b","i"); if (text.match(textPattern)) { postHidden = true; break; } } } } if (!postHidden && (filterAction == filterActionEnum.COMMENTSONLY || filterAction == filterActionEnum.POSTSANDCOMMENTS)) { // this is a comment or post copy and it should be subject to filtering // check for matching links currentNode = copyDiv.firstChild; var link = null; while (currentNode) { if (currentNode.nodeName === "A") { link = currentNode.getAttribute('href'); for (var j = 0; link && j < siteFilters.length; j++) { var sitePattern = new RegExp("^(https?://)?"+siteFilters[j]); if (link.match(sitePattern)) { postHidden = true; break; } } } currentNode = currentNode.nextSibling; } if (!postHidden) { // check for text var text = copyDiv.textContent; for (var j = 0; j < textFilters.length; j++) { var textPattern = new RegExp("\\b"+textFilters[j]+"\\b","i"); if (text.match(textPattern)) { postHidden = true; break; } } } } if (postHidden) { if (titleDiv) { titleDiv.style.display = noneText; } copyDiv.style.display = noneText; // try and squash the trailing BR, or 2 var sibling = copyDiv.nextSibling; while (sibling) { if (sibling.nodeName === 'BR') { // found it sibling.style.display = noneText; } else if (sibling.nodeName !== '#text') { // apparently shot past the post/comment entry, bail break; } sibling = sibling.nextSibling; } } } } function buildContextMenu() { var menu = document.body.appendChild(document.createElement("menu")); menu.outerHTML = '<menu id="userscript-context-menu" type="context">\ <menu label="diediedead!">\ <menuitem id="filter_user_or_content" label="'+noActiveSelectionText+'">\ </menuitem>\ <menuitem label="\u2014">\ </menuitem>\ <menuitem id="show_all_content" type="checkbox" label="'+showAllContextText+'">\ </menuitem>\ <menuitem id="filter_posts_and_comments" type="checkbox" label="'+filterPostsAndComments+'">\ </menuitem>\ <menuitem id="filter_posts_only" type="checkbox" label="'+filterPostsOnly+'">\ </menuitem>\ <menuitem id="filter_comments_only" type="checkbox" label="'+filterCommentsOnly+'">\ </menuitem>\ <menuitem label="\u2014">\ </menuitem>\ <menuitem id="configure_filters" label="'+configureFilters+'">\ </menuitem>\ </menu>\ </menu>'; var html = document.documentElement; html.setAttribute("contextmenu", "userscript-context-menu"); if ("contextMenu" in html && "HTMLMenuItemElement" in window) { $("#userscript-context-menu menu").addEventListener("click", contextClick, false); html.addEventListener("contextmenu", initMenu, false); } } function buildConfigureBox() { var mainDiv = document.createElement('div'); mainDiv.id = "div_configureBox"; var userTextArea = document.createElement('textarea'); userTextArea.id = "userTextArea"; userTextArea.className = "textarea_configureBox"; var contentTextArea = document.createElement('textarea'); contentTextArea.id = "contentTextArea"; contentTextArea.className = "textarea_configureBox"; var siteTextArea = document.createElement('textarea'); siteTextArea.id = "siteTextArea"; siteTextArea.className = "textarea_configureBox"; var h2 = document.createElement('h2'); h2.className = "header_configureBox"; h2.appendChild(document.createTextNode('Configure diediedead')); mainDiv.appendChild(h2); mainDiv.appendChild(document.createTextNode('Filter users (one per line)')); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(userTextArea); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(document.createTextNode('Filter if contains text (1 entry/line)')); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(contentTextArea); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(document.createTextNode('Filter if contains site (1 site/line)')); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(siteTextArea); mainDiv.appendChild(document.createElement('br')); var radio = document.createElement("input"); radio.id = "radio_ShowAll"; radio.type = "radio"; radio.name = "showWhich"; if (filterAction == filterActionEnum.NONE) { radio.checked = true; } mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(radio); mainDiv.appendChild(document.createTextNode(showAllContextText)); radio = document.createElement("input"); radio.id = "radio_CommentsAndPosts"; radio.type = "radio"; radio.name = "showWhich"; if (filterAction == filterActionEnum.POSTSANDCOMMENTS) { radio.checked = true; } mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(radio); mainDiv.appendChild(document.createTextNode(filterPostsAndComments)); radio = document.createElement("input"); radio.id = "radio_PostsOnly"; radio.type = "radio"; radio.name = "showWhich"; if (filterAction == filterActionEnum.POSTSONLY) { radio.checked = true; } mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(radio); mainDiv.appendChild(document.createTextNode(filterPostsOnly)); radio = document.createElement("input"); radio.id = "radio_CommentsOnly"; radio.type = "radio"; radio.name = "showWhich"; if (filterAction == filterActionEnum.COMMENTSONLY) { radio.checked = true; } mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(radio); mainDiv.appendChild(document.createTextNode(filterCommentsOnly)); mainDiv.appendChild(document.createElement('br')); mainDiv.appendChild(document.createElement('br')); var saveNode = document.createElement("button"); saveNode.appendChild(document.createTextNode("Save")); saveNode.className = "button_configureBox"; saveNode.addEventListener("click", saveConfiguration, true); mainDiv.appendChild(saveNode); mainDiv.style.display = noneText; document.getElementsByTagName('body')[0].appendChild(mainDiv); } function showConfigure() { loadConfiguration(); var div = $("#div_configureBox"); div.style.display = blockText; } function initMenu(e) { var menuitem = $("#show_all_content"); menuitem.checked = false; menuitem = $("#filter_posts_and_comments"); menuitem.checked = false; menuitem = $("#filter_posts_only"); menuitem.checked = false; menuitem = $("#filter_comments_only"); menuitem.checked = false; menuitem = $("#filter_user_or_content") menuitem.label = noActiveSelectionText; switch(filterAction) { case filterActionEnum.POSTSANDCOMMENTS: menuitem = $("#filter_posts_and_comments"); menuitem.checked = true; break; case filterActionEnum.POSTSONLY: menuitem = $("#filter_posts_only"); menuitem.checked = true; break; case filterActionEnum.COMMENTSONLY: menuitem = $("#filter_comments_only"); menuitem.checked = true; break; case filterActionEnum.NONE: default: menuitem = $("#show_all_content"); menuitem.checked = true; break; } var node = e.target; var pNode = node; // fanfare does a user link of //www.metafilter.com, don't ask me if (pNode.nodeName == 'A' && pNode.target && pNode.target == "_self" && pNode.getAttribute("href").match(/^((https?:\/\/)|(\/\/))?(www.metafilter.com)?\/user\/\d+$/)) { // right click on user link menuitem = $("#filter_user_or_content") menuitem.label = filterForUser + pNode.innerHTML; return; } while (pNode && pNode.nodeName != "A") { pNode = pNode.parentNode; } if (pNode && pNode.hasAttribute("href")) { // right click on a site link var result = pNode.getAttribute("href").match(/^(https?:\/\/)?([^\/\?]{3,})/); if (!result || !result[2]) { return; } menuitem = $("#filter_user_or_content") menuitem.label = filterForSite + result[2]; } else { // right click on text, see if selected var text = document.getSelection().toString(); if (text) { text.trim(); } if (text.length < 1) { return; } menuitem = $("#filter_user_or_content"); menuitem.label = filterForText + text; } return; } function $(aSelector, aNode) { return (aNode || document).querySelector(aSelector); } document.addEventListener('DOMContentLoaded',onLoaded,true); GM_registerMenuCommand(configureFilters, showConfigure, "c");
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址