Sleazy Fork is available in English.

f95zone tweaks

f95zone exclude tags and min like filter

Från och med 2021-04-21. Se den senaste versionen.

// ==UserScript==
// @name        f95zone tweaks
// @namespace   f95zone tweaks
// @description f95zone exclude tags and min like filter
// @match       https://f95zone.to/latest/
// @version     1.0
// @author      3xd_tango
// @require     https://cdn.jsdelivr.net/combine/npm/@violentmonkey/dom@1,npm/@violentmonkey/ui@0.5
// @grant       GM_addStyle
// @grant       GM_getValue
// @grant       GM_setValue
// ==/UserScript==

(function () {
'use strict';

var css_248z = ".customTags{border-radius:2px;box-shadow:0 0 0 0 transparent,0 1px 1px 0 rgba(0,0,0,.15),0 1px 2px 0 rgba(0,0,0,.15);display:inline-block;font-size:.8em;line-height:1.8em;margin:4px 4px 0 0;padding:0 6px;text-shadow:1px 1px 2px rgba(0,0,0,.75)}.selected-tags-wrap span:hover{background-color:#ba4545}.selected-tags-wrap span{background-color:#181a1d;border-radius:3px;cursor:pointer;display:inline-block;font-size:.9em;line-height:24px;margin:4px 4px 0 0;padding:0 6.66667px;transition:.2s}";

let like_limit = GM_getValue('like_limit', 200);
let dislikes = GM_getValue('dislikes', ['female protagonist', 'text based', 'mind control']);
let likes = GM_getValue('likes', [['incest', '#ff0000'], ['harem', '#0011ff']]);
function mainFilter() {
  init();
  return VM.createElement(VM.Fragment, null, VM.createElement("div", {
    className: "filter-block"
  }, VM.createElement("h4", {
    className: "filter-block_title"
  }, "Tags Like Limits"), VM.createElement("div", {
    className: "selectize-input"
  }, VM.createElement("input", {
    value: like_limit,
    autoComplete: "off",
    style: "width: 127px;",
    onChange: limitHandler
  }))), VM.createElement("div", {
    className: "filter-block"
  }, VM.createElement("h4", {
    className: "filter-block_title"
  }, "Like Tags"), VM.createElement("div", {
    className: "filter-block_content"
  }, VM.createElement("div", {
    className: "selectize-input"
  }, VM.createElement("input", {
    autoComplete: "off",
    placeholder: "Enter a tag to filter...",
    style: "width: 127px; opacity: 1; position: relative; left: 0px;",
    onChange: likeHandler
  })), VM.createElement("div", {
    className: "selected-tags-wrap"
  }, likes.map(dl => VM.createElement("span", {
    onClick: tagRemoveHandler1
  }, dl[0]))))), VM.createElement("div", {
    className: "filter-block"
  }, VM.createElement("h4", {
    className: "filter-block_title"
  }, "Dislike Tags"), VM.createElement("div", {
    className: "filter-block_content"
  }, VM.createElement("div", {
    className: "selectize-input"
  }, VM.createElement("input", {
    autoComplete: "off",
    placeholder: "Enter a tag to filter...",
    style: "width: 127px; opacity: 1; position: relative; left: 0px;",
    onChange: dislikeHandler
  })), VM.createElement("div", {
    className: "selected-tags-wrap"
  }, dislikes.map(dl => VM.createElement("span", {
    onClick: tagRemoveHandler
  }, dl))))), VM.createElement("style", null, css_248z));
}
function init() {
  const element = document.querySelectorAll('.resource-tile');

  if (element[0]) {
    likeFilter();
    dislikeFilter();
    likeLimit();
  } else {
    setTimeout(init, 100);
  }
}

function tagRemoveHandler(event) {
  dislikes = dislikes.filter(r => r !== event.target.textContent);
  event.target.remove();
  GM_setValue('dislikes', dislikes);
  dislikeFilter();
}

function tagRemoveHandler1(event) {
  likes = likes.filter(r => r[0] !== event.target.textContent);
  event.target.remove();
  GM_setValue('likes', likes);
  likeFilter();
}

function likeHandler(event) {
  let x;

  do {
    x = prompt('Please Enter the Color in Hex');
  } while (!x.includes('#') && x === '' && x.length <= 1);

  if (x !== null) {
    const tag = [event.target.value, x];
    likes.push(tag);
    GM_setValue('likes', likes);
    let node = document.createElement("SPAN");
    node.onclick = tagRemoveHandler1;
    node.appendChild(document.createTextNode(event.target.value));
    document.querySelector('.selected-tags-wrap').append(node);
    likeFilter();
  }
}

function dislikeHandler(event) {
  const tagName = event.target.value;
  dislikes.push(tagName);
  GM_setValue('dislikes', dislikes);
  event.target.value = '';
  let node = document.createElement("SPAN");
  node.onclick = tagRemoveHandler;
  node.appendChild(document.createTextNode(tagName));
  document.querySelector('.selected-tags-wrap').append(node);
  dislikeFilter();
}

function limitHandler(event) {
  like_limit = event.target.value;
  GM_setValue('like_limit', like_limit);
  likeLimit();
}

function likeFilter() {
  const element = document.querySelectorAll('.resource-tile');
  document.querySelectorAll('.customTags').forEach(e => e.remove());

  for (let i = 0; i < element.length; i++) {
    console.debug(element[i]);

    if (element[i].style.display === 'none') {
      continue;
    }

    let node = document.createElement("DIV");
    const dataTags = element[i].dataset.tags.split(',');
    node.style.padding = '.5rem 0';

    for (let j = likes.length - 1; j >= 0; j--) {
      if (dataTags.includes(likes[j][0])) {
        let node1 = document.createElement("SPAN");
        node1.classList.add('customTags');
        node1.style.backgroundColor = likes[j][1];
        element[i].style.boxShadow = `0px 0px 10px 1px ${likes[j][1]}`;
        node1.appendChild(document.createTextNode(likes[j][0]));
        node.appendChild(node1);
        element[i].setAttribute('isDisplay', 'true');
      } else if (element[i].getAttribute('isDisplay') === null) {
        element[i].setAttribute('isDisplay', 'false');
      }
    }

    if (element[i].style.display !== 'none') {
      try {
        element[i].childNodes[0].childNodes[1].childNodes[1].appendChild(node);
      } catch (e) {
        console.error(e);
        likeFilter();
      }
    }
  }
}

function dislikeFilter() {
  const element = document.querySelectorAll('.resource-tile');

  for (let i = 0; i < element.length; i++) {
    const dataTags = element[i].dataset.tags.split(',');
    const isFP = checkTags(element[i], dataTags);

    if (isFP) {
      element[i].style.setProperty("display", "block", "important");
      element[i].style.setProperty("height", "unset", "important");
      element[i].style.setProperty("margin", "unset", "important");
    } else {
      element[i].style.setProperty("display", "none", "important");
      element[i].style.setProperty("height", "0px", "important");
      element[i].style.setProperty("margin", "0px", "important");
    }
  }
}

function likeLimit() {
  const element = document.querySelectorAll('.resource-tile');

  if (like_limit === '') {
    like_limit = -1;
  }

  for (let i = 0; i < element.length; i++) {
    const element_likes = element[i].childNodes[0].childNodes[1].childNodes[1].childNodes[1].childNodes[1].innerHTML;

    if (Number(element_likes) <= Number(like_limit)) {

      if (element[i].getAttribute('isDisplay') === 'false') {
        element[i].style.setProperty('display', 'none', 'important');
        element[i].style.setProperty('height', '0px', 'important');
        element[i].style.setProperty('margin', '0px', 'important');
      }
    } else {
      element[i].style.setProperty("display", "block", "important");
      element[i].style.setProperty("height", "unset", "important");
      element[i].style.setProperty("margin", "unset", "important");
    }
  }
}

function checkTags(element, dataTags) {
  let tagProt = ['female protagonist', 'male protagonist', 'futa/trans protagonist'];
  const tagProtNames = dislikes.filter(e => e.includes('protagonist'));
  const b = [];
  let c = 0;
  let a = false;
  dataTags.forEach(e => {
    if (tagProtNames.length >= 1) {
      if (tagProtNames.includes(e)) {
        b.push(e);
        return;
      }
    }

    if (dislikes.includes(e)) {
      c += 1;
    }
  });
  console.debug(c);

  if (c > 0) {
    return false;
  }

  if (b.length > 0) {
    b.forEach(e => {
      tagProt = tagProt.filter(r => r !== e);
    });

    for (let i = tagProt.length - 1; i >= 0; i--) {
      if (dataTags.includes(tagProt[i])) {
        return true;
      }

      a = true;
    }
  }

  console.debug(`b = ${b} tagProt = ${tagProt}`);
  return !a;
}

document.querySelector('.content-block_filter').append(mainFilter());

history.onpushstate = function (state) {
  setTimeout(init, 200);
};

(function (history) {
  var pushState = history.pushState;

  history.pushState = function (state) {
    if (typeof history.onpushstate == "function") {
      history.onpushstate({
        state: state
      });
    }

    return pushState.apply(history, arguments);
  };
})(window.history);

}());