Hitomi - Language & Tag Filtering

Filters search results by languages and tags

Stan na 12-12-2018. Zobacz najnowsza wersja.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

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

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==UserScript==
// @name         Hitomi - Language & Tag Filtering
// @namespace    brazenvoid
// @version      2.3
// @author       brazenvoid
// @license      GPL-3.0-only
// @description  Filters search results by languages and tags
// @include      https://hitomi.la/*
// @run-at       document-idle
// ==/UserScript==

// Define languages to keep and tags to exclude here 

let settings = {
	allowedLanguages: [
  	"japanese", 
  	"english"
	],
	excludedTags: [
  	"female:loli", 
  	"sample", 
  	"male:yaoi"
	]
};

// Formatting filters

let formatFilters = function (filters, prefix, suffix) {
  
  for (let index = 0; index < filters.length; index++) {
    
  	filters[index] = '[href="'+ prefix + encodeURIComponent(filters[index]) + suffix +'.html"]';
	}
	return filters.join(", ");
};

let languageFiltersSelector = formatFilters(settings.allowedLanguages, "/index-", "-1");
let tagFiltersSelector = formatFilters(settings.excludedTags, "/tag/", "-all-1");

// Filteration logic

let validateLanguage = function (gallery) {
  
  let validationCheck = true;
  
  if (settings.allowedLanguages.length > 0) {
    
    let languageTD = gallery.querySelector('tr:nth-child(3) > td:nth-child(2)');
    if (languageTD.querySelector('a') !== null) {
      validationCheck = languageTD.querySelectorAll(languageFiltersSelector).length > 0;
    }
  }
  return validationCheck;
};

let validateTags = function (gallery) {
  
  let validationCheck = true;
  
  if (settings.excludedTags.length > 0) {    
    validationCheck = gallery.querySelectorAll(tagFiltersSelector).length === 0;
  }
  return validationCheck;
};

let complianceCallback = function(target) {
  
  let galleries = target.querySelectorAll('.manga, .dj, .acg'), removeGallery = false, languageTD;
  
  for (let gallery of galleries) {

    validationCheck = validateLanguage(gallery) && validateTags(gallery);
    
    if (!validationCheck) {
      gallery.remove();
    }
  }
};

// Setting up configuration and galleries list node

let galleriesList = document.querySelector('.gallery-content');
let observerConfig = { 
  attributes: false, 
  childList: true, 
  subtree: false 
};

// Checking compliance in case of gallery page

complianceCallback(galleriesList);

// Adding observer to check compliance of galleries on search pages

let observer = new MutationObserver(function(mutations, observer) {
  for(let mutation of mutations) {
    complianceCallback(mutation.target);
  }
});
observer.observe(galleriesList, observerConfig);