Ehentai Simliar Gallery

Search Simliar Gallery

// ==UserScript==
// @name         Ehentai Simliar Gallery
// @name:zh-CN   E绅士相似画廊
// @namespace    https://greasyfork.org/zh-CN/users/51670-ruaruarua
// @version      0.1.1
// @author       ruaruarua
// @description  Search Simliar Gallery
// @description:zh-cn 搜索相似画廊
// @match        https://exhentai.org/g/*
// @match        https://e-hentai.org/g/*
// @icon         https://exhentai.org/favicon.ico
// ==/UserScript==
(() => {
  "use strict";

  /**
   * https://github.com/seven332/EhViewer/blob/ba6d41b91f53b0835f73fb2903b5c4ff1259786c/app/src/main/java/com/hippo/ehviewer/client/EhUtils.java#L150
   */

  const galleryTitle =
    document.querySelector("#gn")?.textContent ||
    document.querySelector("#gj")?.textContent;
  if (!galleryTitle) return;

  // Remove [XXX], (XXX), {XXX}, ~XXX~ stuff
  const PATTERN_TITLE_PREFIX =
    /^(?:(?:\([^)]*\))|(?:\[[^\]]*\])|(?:\{[^}]*\})|(?:~[^~]*~)|\s+)*/g;
  // Remove [XXX], (XXX), {XXX}, ~XXX~ stuff and something like ch. 1-23
  const PATTERN_TITLE_SUFFIX =
    /(?:\s+ch.[\s\d-]+)?(?:(?:\([^)]*\))|(?:\[[^\]]*\])|(?:\{[^}]*\})|(?:~[^~]*~)|\s+)*$/gi;

  const sideBar = document.querySelector("#gd5");
  const node = sideBar.querySelector(".g2").cloneNode(true);
  const anchor = node.querySelector("a");

  let extractTitle = galleryTitle
    .replaceAll(PATTERN_TITLE_PREFIX, "")
    .replaceAll(PATTERN_TITLE_SUFFIX, "");
  if (!extractTitle) return;

  // Sometimes title is combined by romaji and english translation.
  // Only need romaji.
  // TODO But not sure every '|' means that
  const separateIndex = extractTitle.indexOf("|");
  if (separateIndex >= 0) {
    extractTitle = extractTitle.slice(0, separateIndex);
  }
  anchor.href = `/?f_search="${encodeURIComponent(extractTitle)}"&advsearch=1`;

  anchor.removeAttribute("onclick");
  anchor.textContent = "Simliar Gallery";
  sideBar.appendChild(node);
})();