Danbooru Fast Blacklist

hides dannbooru posts faster

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        Danbooru Fast Blacklist
// @namespace   Violentmonkey Scripts
// @match       *://danbooru.*.us/*
// @match       *://safebooru.*.us/*
// @match       *://aibooru.online/*
// @grant       none
// @version     1.0
// @run-at      document-start
// @author      -
// @description hides dannbooru posts faster
// ==/UserScript==


(() => {

function getBlacklistedTags() {
  let head = document.head;
  if (! head) return [];

  let blacklistedTags = head.querySelector('meta[name="blacklisted-tags"]');
  if (blacklistedTags) {
    return blacklistedTags.content.split(',') // ['1 2 3', '4 5 7']
      .map((tags) => tags.split(' ')); // [['1','2','3'], ['4','5','6'], ...]
  } else {
    return [];
  }
}

function getAllPosts() {
  return document.querySelectorAll('article.post-preview');
}

function getCurrentPost() {
  let content = document.getElementById('content');
  if (content) {
    return content.querySelector('section.image-container');
  } else {
    return null;
  }
}

function areTagsMatchingPost(postTags, searchTags) {
  if (typeof postTags !== 'string') {
    postTags = Array.from(postTags);
    postTags = postTags.map((tag) => tag.replaceAll(' ', '_'));
    postTags = postTags.join(' ');
  } // postTags = 'touhou 1girl smile yakumo_yukari'
  if (typeof searchTags === 'string') {
    searchTags = searchTags.split(' ');
  } // searchTags = ['touhou', '~1girl', '~smile', 'yakumo_yukari', '-crying']

  // ~tag
  function checkUnionTags(tags) { // tags = ['tag1', 'tag2', 'tag3', ...]
    if (tags.length == 0) return true;

    for (let tag of tags) {
      if (postTags.includes(tag)) {
        return true;
      }
    }
    return false;
  }
  // -tag
  function checkDifferenceTags(tags) { // tags = ['tag1', 'tag2', 'tag3', ...]
    if (tags.length == 0) return true;

    for (let tag of tags) {
      if (postTags.includes(tag)) {
        return false;
      }
    }
    return true;
  }
  // tag
  function checkIntersectionTags(tags) { // tags = ['tag1', 'tag2', 'tag3', ...]
    if (tags.length == 0) return true;

    for (let tag of tags) {
      if (!postTags.includes(tag)) {
        return false;
      }
    }
    return true;
  }


  let union = [];        // ~tag
  let difference = [];   // -tag
  let intersection = []; // tag

  for (let tag of searchTags) {
    if (tag[0] === '~') {
      union.push(tag.slice(1));
    } else if (tag[0] === '-') {
      difference.push(tag.slice(1));
    } else {
      intersection.push(tag);
    }
  }

  return checkUnionTags(union)
  && checkDifferenceTags(difference)
  && checkIntersectionTags(intersection);
}

function hideAllBlacklistedPosts() {
  let BlacklistedTags = getBlacklistedTags();
  let posts = getAllPosts();

  for (let post of posts) {
    for (let tags of BlacklistedTags) {
      if (areTagsMatchingPost(post.dataset.tags, tags)) {
        post.classList.add('blacklisted-active');
        break;
      }
    }
  }
}

function hideCurrentBlacklistedPost() {
  let currentPost = getCurrentPost();
  let blacklistedTags = getBlacklistedTags();
  if (currentPost) {
    for (let tags of blacklistedTags) {
      if (areTagsMatchingPost(currentPost.dataset.tags, tags)) {
        currentPost.classList.add('blacklisted-active');
        break;
      }
    }
  }
}

function apply() {
  let listenerAttached = false;
  new MutationObserver((mutations, observer) => {
    if (!listenerAttached) {
      document.addEventListener('DOMContentLoaded', () => observer.disconnect());
      listenerAttached = true;
    }

    hideCurrentBlacklistedPost();
    hideAllBlacklistedPosts();
  }).observe(document.documentElement, {childList:true, subtree: true});
}

apply();

})();