Hides those pesky Visual Novels everyone's complaining about.
// ==UserScript==
// @name Itch.io Hide Visual Novels
// @namespace itchiohide
// @description Hides those pesky Visual Novels everyone's complaining about.
// @version 1.0
// @match *://itch.io/*
// @grant GM_addStyle
// @run-at document-end
// @license public domain
// @icon https://www.google.com/s2/favicons?domain=itch.io
// ==/UserScript==
// Inspired by greasyfork.org/scripts/464588, but remade to not use extra network traffic.
(function() {
'use strict';
console.log("Itch.io Visual Novel Filter script running");
// Inject CSS to hide elements that we mark as hidden
GM_addStyle(`
.hidden-visual-novel {
display: none !important;
}
`);
// Optional: If you want unfiltered game thumbnails to appear blurred until processed,
// you can enable the following CSS (set BLUR to true).
// However, since this is almost instant, this realistically does nothing.
var BLUR = false;
if(BLUR) {
GM_addStyle(`
.filterable .game_cell:not(.filtered) > .game_thumb {
filter: blur(0.5em);
}
`);
}
// Optional status display: shows how many games have been hidden.
var statview = function() {
return `<div id="itchvnfilterstat" style="margin-bottom: 1em; color:#858585">
Visual Novels hidden: ${document.querySelectorAll('.hidden-visual-novel').length}
</div>`;
};
var stat = function() {
var old = document.querySelector('#itchvnfilterstat');
if(old) old.remove();
var gridOuter = document.querySelector('.grid_outer');
if(gridOuter) {
gridOuter.prepend(new DOMParser().parseFromString(statview(), "text/html").body.firstElementChild);
}
};
stat();
// Filtering function modeled on the original script's loop.
// It looks for a container holding the games and then processes each unqueued game cell.
var filtering = function() {
var m = document.querySelector('[id*="browse_games_"],[id*="browse_assets_"],[id*="search_"]');
if(m) {
document.body.classList.add('filterable');
// Process any game_cell that hasn't yet been queued for filtering
var cells = m.querySelectorAll('.game_cell:not(.filteringqueued)');
cells.forEach(function(g) {
g.classList.add('filteringqueued');
// Instead of fetching tags, we simply check the text of .game_genre
var genreElem = g.querySelector('.game_genre');
if(genreElem) {
var genreText = genreElem.textContent.trim().toLowerCase();
if(genreText.includes("visual novel")) {
g.classList.add('hidden-visual-novel');
}
}
g.classList.add('filtered');
});
stat();
}
requestAnimationFrame(filtering);
};
filtering();
})();