Fanfou Local Blacklist

为饭否网页端加入了本地屏蔽功能,只要消息转发链中包含屏蔽列表中的用户,就能屏蔽那条消息。(暂时不能考虑因为消息过长被挤掉的用户)

// ==UserScript==
// @name         Fanfou Local Blacklist
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  为饭否网页端加入了本地屏蔽功能,只要消息转发链中包含屏蔽列表中的用户,就能屏蔽那条消息。(暂时不能考虑因为消息过长被挤掉的用户)
// @author       You
// @include      http://www.fanfou.com/*
// @include      http://fanfou.com/*
// @include      https://www.fanfou.com/*
// @include      https://fanfou.com/*
// @grant    GM_getValue
// @grant    GM_setValue
// @grant    GM_addStyle
// @run-at document-start
// ==/UserScript==

var settingsPage = async function() {
  var li = document.querySelector('#settings ul>li:nth-last-child(2)');
  li.firstChild.textContent = '屏蔽';
  if (li.classList.contains('current')) {
    var container = document.querySelector('#settings .nf');
    // Empty the container
    var range = document.createRange();
    range.selectNodeContents(container);
    range.deleteContents();

    // Add filter options
    // No better and convinient way, style and dom conform to fanfou's original design
    var words = await GM_getValue('filter_words');
    if (!words) words = '[]';
    words = JSON.parse(words);
    var display_words = words.join("\n");
    var textarea = document.createElement('textarea');
      textarea.id = 'filter_words';
      textarea.name = 'filter_words_list';
      textarea.rows = Math.min(20, Math.max(10, words.length));
      textarea.cols = 50;
      textarea.value = display_words;
    var label = document.createElement('label');
      label.classList.add('label_input');
      label.htmlFor = textarea.id;
      label.textContent = '屏蔽词列表(回车分隔)';
    var p1 = document.createElement('p');
    p1.style.margin = '10px 0';
    p1.appendChild(label);
    p1.appendChild(textarea);

    var input = document.createElement('input');
    input.type = 'button';
    input.classList.add('formbutton');
    input.value = '保存';
    var clicking = false;
    input.onclick = async function() {
      if (!clicking) {
        clicking = true;
        words = textarea.value.split("\n");
        await GM_setValue('filter_words', JSON.stringify(words));
        clicking = false;
      }
    };
    var p2 = document.createElement('p');
    p2.classList.add('act');
    p2.appendChild(input);
    container.appendChild(p1);
    container.appendChild(p2);
  }
};

var usersPage = async function(list) {
  var url = decodeURIComponent(window.location.pathname);
  var blocked = list.includes(url);
  var actions = document.querySelector('#panel .actions');
  if (actions === null)
    actions = document.querySelector('#profile-protected .actions');
  var addButton = document.createElement('a');
  addButton.href = 'javascript:void(0);';
  var setButton = function(b) {
    addButton.className = b?'bl':'bh';
    addButton.text = b?'取消屏蔽':'本地屏蔽';
  };
  var clicking = false;
  addButton.onclick = async function(e) {
    if (clicking) return false;
    clicking = true;
    if (blocked) {
      var index = list.indexOf(url);
      list.splice(index, 1);
    } else {
      list.push(url);
    }
    blocked = !blocked;
    setButton(blocked);
    await GM_setValue('blacklist', JSON.stringify(list));
    clicking = false;
  };
  setButton(blocked);
  actions.appendChild(addButton);
};

var homePage = async function(list) {
  var words = await GM_getValue('filter_words');
  if (!words) words = '[]';
  words = JSON.parse(words);
  var watch = function(target, mutate) {
    var updating = false;
    //var target = document.querySelector(selector);
    var UpdateTL = function() {
      if (updating) return;
      updating = true;
      var messages = target.children;
      //var bad_msgs = [];
      for (var i=0; i<messages.length; ++i) {
        var message = messages[i];
        var bad = false;
        var users = Array.from(message.querySelectorAll('.former'));
        users.push(message.querySelector('.author'));
        var blames = [];
        bad = bad || list.some(function(path){
          return users.some(function(user){
            var res = decodeURIComponent(user.href).endsWith(decodeURIComponent(path));
            if (res) blames.push('@'+user.textContent);
            return res;
          });
        });
        var messageContent = message.querySelector('.content').textContent;
        bad = bad || words.some(function(word){
          var res = word.length > 0 && messageContent.includes(word);
          if (res) blames.push(word);
          return res;
        });
        //if (bad) bad_msgs.push(message);
        if (!bad) message.classList.add("good"); else {
          message.setAttribute("data-blame", "因" + blames.join(',') + "而被屏蔽");
          message.classList.add("bad");
        }
      }
      //bad_msgs.forEach(function(msg) {msg.remove();});
      updating = false;
    };
    var observer = new MutationObserver(UpdateTL);
    observer.observe(mutate, {childList: true});
    UpdateTL();
  };
  var stream = document.querySelector('#stream ol');
  watch(stream, stream);
  window.onhashchange = function(){
    var stream = document.querySelector('#stream ol');
    console.log(stream);
    watch(stream, stream);
  };
  //if (location.hash.length > 0) watch('#stream ol', document.querySelector('#main'));

  stream.onclick = function(e) {
    if (e.target.classList.contains('bad')) {
      e.target.classList.toggle('trouble');
    }
  };

  var navbar = document.querySelector('#navigation .ui-roundedbox-content>ul');
  var a = document.createElement('a');
  a.textContent = '取消屏蔽';
  a.href = ' ';
  var clicking = false;
  a.onclick = function(e) {
    var stream = document.querySelector('#stream ol');
    e.preventDefault();
    if (!clicking) {
      clicking = true;
      if (a.textContent == '取消屏蔽') {
        a.textContent = '恢复屏蔽';
      } else {
        a.textContent = '取消屏蔽';
      }
      for (var i=0; i<stream.children.length; ++i) {
        stream.children[i].classList.toggle('unblock');
      }
      clicking = false;
    }
    return false;
  };
  var li = document.createElement('li');
  li.appendChild(a);
  navbar.appendChild(li);
};

(async function() {
  'use strict';
  if (window.location.pathname == '/home' || window.location.pathname == '/mentions') {
    GM_addStyle('#stream>ol>li { display:none }');
    GM_addStyle('#stream>ol>li.good { display:block }');
    GM_addStyle('#stream>ol>li.bad.unblock { display:block }');
    GM_addStyle('#stream>ol>li.bad:not(.trouble)>.content { filter: blur(10px) }');
    GM_addStyle('#stream>ol>li.bad:not(.trouble)>.author { filter: blur(10px) }');
    GM_addStyle('#stream>ol>li.bad:not(.trouble)>.stamp { filter: blur(10px) }');
    GM_addStyle('#stream>ol>li.bad:not(.trouble)>.avatar { filter: blur(10px) grayscale(100%) }');
    GM_addStyle(`#stream>ol>li.bad:not(.trouble)::before { 
      text-align: center;
      font-size: 1em;
      position: absolute;
      content: attr(data-blame);
      width: 100%;
      display: flex;
      height: 100%;
      top: 0;
      left: 0;
      justify-content: center;
      align-items: center;
      color: firebrick;
    }`);
  }

  var list = await GM_getValue('blacklist');
  if (!list) list = '[]';
  list = JSON.parse(list);
  list = list.map(id => decodeURIComponent(id));

  document.addEventListener("DOMContentLoaded", async function(){
    if (window.location.pathname.startsWith('/settings')) {
      await settingsPage();
    } else if (window.location.pathname != '/home' && window.location.pathname != '/mentions') {
      await usersPage(list);
    } else {
      await homePage(list);
    }
  });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址