您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Clone search page navigation on top for mobile and options for faster tag filtering in top bar
// ==UserScript== // @name nhentai Navigation Improvements // @description Clone search page navigation on top for mobile and options for faster tag filtering in top bar // @namespace xspeed.net // @license MIT // @version 4 // @icon https://nhentai.net/favicon.ico // @match *://nhentai.net/* // @grant none // ==/UserScript== "use strict"; function showTextPrompt(msg) { const text = document.createElement("p"); text.innerText = msg; const input = document.createElement("input"); input.type = "search"; const link = document.createElement("i"); link.className = "fa fa-paste"; const button = document.createElement("button"); button.className = "btn btn-primary btn-square"; button.type = "submit"; button.appendChild(link); const form = document.createElement("form"); form.className = "search"; form.role = "search"; form.method = "dialog"; form.appendChild(input); form.appendChild(button); const dialog = document.createElement("dialog"); dialog.appendChild(text); dialog.appendChild(form); const style = getComputedStyle(document.body); dialog.style.backgroundColor = style.getPropertyValue("background-color"); dialog.style.color = style.getPropertyValue("color"); document.body.appendChild(dialog); dialog.showModal(); return new Promise((resolve, reject) => form.addEventListener('submit', () => { resolve(input.value); dialog.remove(); }, { once: true })); } function stopEvent(event) { event.stopImmediatePropagation(); event.preventDefault(); } async function onChangeTags(event, tags) { stopEvent(event); const input = document.querySelector("input[type=search]"); const str = tags ?? await showTextPrompt("Specify tags, separate by commas"); if (str) { str.split(',').map(x => x.trim()).filter(x => x).forEach(x => adjustSearch("tag", x, false)); document.querySelector("button[type=submit]").click(); } } function adjustSearch(type, item, add) { const input = document.querySelector("input[type=search]"); item = wrap(item); const act = " " + (add ? item : `-${type}:${item}`); const inv = " " + (add ? `-${type}:${item}` : item); if (input.value.indexOf(inv) != -1) input.value = input.value.replace(inv, act); else if (input.value.indexOf(act) == -1) input.value += act; input.value = input.value.replaceAll(' ', ' '); sessionStorage.setItem("lastSearch", input.value); } function wrap(txt) { return txt.indexOf(" ") == -1 ? txt : `"${txt}"`; } function clearSearch(event) { stopEvent(event); document.querySelector("input[type=search]").value = ""; sessionStorage.removeItem("lastSearch"); } function setupBtn(elem) { if (!elem) return; let item = elem.firstChild.cloneNode(true); let link = item.firstChild; link.href = "#"; link.innerText = "Block default"; link.addEventListener("click", e => onChangeTags(e, "bbm,netorare,vore,scat,guro")); elem.insertBefore(item, elem.firstChild); item = elem.firstChild.cloneNode(true); link = item.firstChild; link.href = "#"; link.innerText = "Block tags"; link.addEventListener("click", onChangeTags); elem.insertBefore(item, elem.firstChild); item = elem.firstChild.cloneNode(true); link = item.firstChild; link.href = "#"; link.innerText = "Clear search"; link.addEventListener("click", e => clearSearch(e)); elem.insertBefore(item, elem.firstChild); } function onTagClick(event, elem, add) { stopEvent(event); const data = elem.pathname.split("/").filter(x => x); adjustSearch(data[0], data[1].replaceAll("-", " "), add); } function setupTag(elem) { if (!elem.querySelector(".count")) return document.createTextNode(""); const container = document.createElement("span"); container.addEventListener("click", e => stopEvent(e)); container.className = "name"; const add = document.createElement("a"); add.href = "#"; add.addEventListener("click", e => onTagClick(e, elem, true)); add.className = "fa fa-plus"; add.style.padding = "0.25em 0em"; add.style.marginRight = "0.4em"; const del = document.createElement("a"); del.href = "#"; del.addEventListener("click", e => onTagClick(e, elem)); del.className = "fa fa-minus"; del.style.padding = "0.25em 0em"; container.appendChild(add); container.appendChild(del); return container; } (function() { const content = document.getElementById("content"); const pagination = document.querySelector("section.pagination"); const input = document.querySelector("input[type=search]"); if (content && pagination) { const clone = pagination.cloneNode(true); const spacer = clone.querySelector(".ios-mobile-webkit-bottom-spacing"); if (spacer) spacer.remove(); content.insertBefore(clone, content.firstChild); } if (!input.value) { input.value = sessionStorage.getItem("lastSearch") ?? "english "; } else if (input.value.trim() != "english") { sessionStorage.setItem("lastSearch", input.value); } setupBtn(document.querySelector("ul.menu")); setupBtn(document.querySelector("ul.dropdown-menu")); document.querySelectorAll(".tags>.tag").forEach(x => x.appendChild(setupTag(x))); })();