Hitomi - Language & Tag Filtering

Filters search results by languages and tags

Version vom 12.12.2018. Aktuellste Version

  1. // ==UserScript==
  2. // @name Hitomi - Language & Tag Filtering
  3. // @namespace brazenvoid
  4. // @version 2.3
  5. // @author brazenvoid
  6. // @license GPL-3.0-only
  7. // @description Filters search results by languages and tags
  8. // @include https://hitomi.la/*
  9. // @run-at document-idle
  10. // ==/UserScript==
  11.  
  12. // Define languages to keep and tags to exclude here
  13.  
  14. let settings = {
  15. allowedLanguages: [
  16. "japanese",
  17. "english"
  18. ],
  19. excludedTags: [
  20. "female:loli",
  21. "sample",
  22. "male:yaoi"
  23. ]
  24. };
  25.  
  26. // Formatting filters
  27.  
  28. let formatFilters = function (filters, prefix, suffix) {
  29. for (let index = 0; index < filters.length; index++) {
  30. filters[index] = '[href="'+ prefix + encodeURIComponent(filters[index]) + suffix +'.html"]';
  31. }
  32. return filters.join(", ");
  33. };
  34.  
  35. let languageFiltersSelector = formatFilters(settings.allowedLanguages, "/index-", "-1");
  36. let tagFiltersSelector = formatFilters(settings.excludedTags, "/tag/", "-all-1");
  37.  
  38. // Filteration logic
  39.  
  40. let validateLanguage = function (gallery) {
  41. let validationCheck = true;
  42. if (settings.allowedLanguages.length > 0) {
  43. let languageTD = gallery.querySelector('tr:nth-child(3) > td:nth-child(2)');
  44. if (languageTD.querySelector('a') !== null) {
  45. validationCheck = languageTD.querySelectorAll(languageFiltersSelector).length > 0;
  46. }
  47. }
  48. return validationCheck;
  49. };
  50.  
  51. let validateTags = function (gallery) {
  52. let validationCheck = true;
  53. if (settings.excludedTags.length > 0) {
  54. validationCheck = gallery.querySelectorAll(tagFiltersSelector).length === 0;
  55. }
  56. return validationCheck;
  57. };
  58.  
  59. let complianceCallback = function(target) {
  60. let galleries = target.querySelectorAll('.manga, .dj, .acg'), removeGallery = false, languageTD;
  61. for (let gallery of galleries) {
  62.  
  63. validationCheck = validateLanguage(gallery) && validateTags(gallery);
  64. if (!validationCheck) {
  65. gallery.remove();
  66. }
  67. }
  68. };
  69.  
  70. // Setting up configuration and galleries list node
  71.  
  72. let galleriesList = document.querySelector('.gallery-content');
  73. let observerConfig = {
  74. attributes: false,
  75. childList: true,
  76. subtree: false
  77. };
  78.  
  79. // Checking compliance in case of gallery page
  80.  
  81. complianceCallback(galleriesList);
  82.  
  83. // Adding observer to check compliance of galleries on search pages
  84.  
  85. let observer = new MutationObserver(function(mutations, observer) {
  86. for(let mutation of mutations) {
  87. complianceCallback(mutation.target);
  88. }
  89. });
  90. observer.observe(galleriesList, observerConfig);