Hitomi - Language & Tag Filtering

Filters search results by languages and tags

目前為 2019-01-19 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Hitomi - Language & Tag Filtering
// @namespace    brazenvoid
// @version      2.4
// @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 = {
    allowedGallleryTypes: [
        'artist cg',
        'doujinshi',
        'game cg',
        'manga',
    ],
	allowedLanguages: [
  	    "japanese",
  	    "english"
	],
	excludedTags: [
  	    "female:loli",
  	    "sample",
  	    "male:yaoi"
	]
}

// Translate gallery types to css selectors

let allowedGallerySelectors = [], allowedGalleryTypeSelector

for (let allowedGalleryType of settings.allowedGallleryTypes) {
    switch (allowedGalleryType) {
        case 'artist cg':
            allowedGalleryTypeSelector = 'acg'
            break
        case 'doujinshi':
            allowedGalleryTypeSelector = 'dj'
            break
        case 'game cg':
            allowedGalleryTypeSelector = 'cg'
            break
        case 'manga':
            allowedGalleryTypeSelector = 'manga'
            break
        default:
            allowedGalleryTypeSelector = ''
    }
    allowedGallerySelectors.push(allowedGalleryTypeSelector)
}
console.log(allowedGallerySelectors)

// 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 validateType = function (gallery) {
  return allowedGallerySelectors.includes(gallery.className)
}

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

    validationCheck = validateType(gallery) && 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)