Streamline Asuracomic with Search

Removes ads and redundant UI, and adds a button to search for the latest chapter of a series.

// ==UserScript==
// @name         Streamline Asuracomic with Search
// @namespace    Violentmonkey Scripts
// @match        https://asuracomic.net/*
// @grant        none
// @version      1.2
// @author       -
// @license      MIT
// @description  Removes ads and redundant UI, and adds a button to search for the latest chapter of a series.
// ==/UserScript==
;(function () {
  "use strict"

  // --- Add CSS selectors for any elements you want to remove here ---
  const selectorsToRemove = [
    "body > div.flex.items-center.justify-center.flex-col",
    "body > div.max-w-\\[1220px\\].pt-2 > div > div > div > h2.text-center.md\\:text-center.py-4.text-sm.text-\\[\\#999999\\]",
    "body > div.max-w-\\[1220px\\].pt-2 > div > div > div > div.flex.items-center.justify-center.gap-1.py-2",
    "body > div.max-w-\\[1220px\\].pt-2 > div > div > div > div.space-y-4 > div.bg-\\[\\#222222\\].px-5.py-4.flex.items-center.md\\:text-start.justify-center.gap-x-2.w-full",
    "body > div.bottom-\\[-40px\\].sm\\:bottom-0",
  ]

  const applySelectorsToNode = (targetNode) => {
    if (!targetNode || typeof targetNode.querySelectorAll !== "function") {
      return
    }
    for (const selector of selectorsToRemove) {
      try {
        targetNode.querySelectorAll(selector).forEach((el) => el.remove())
        if (targetNode.matches && targetNode.matches(selector)) {
          targetNode.remove()
        }
      } catch (e) {
        console.error(`Failed on selector: ${selector}`, e)
      }
    }
  }

  /**
   * Finds series containers and adds a search button for the latest chapter.
   * @param {Node} targetNode - The node to search within for series containers.
   */
  const addSearchButtons = (targetNode) => {
    if (!targetNode || typeof targetNode.querySelectorAll !== "function") {
      return
    }

    const seriesContainers = targetNode.querySelectorAll("div.col-span-9.space-y-1\\.5")

    seriesContainers.forEach((container) => {
      const titleElement = container.querySelector("span.text-\\[15px\\] a")
      const latestChapterElement = container.querySelector("div.list-disc a p")

      if (!titleElement || !latestChapterElement || container.querySelector(".latest-chapter-search-btn")) {
        return
      }

      const title = titleElement.textContent.trim()
      const chapterText = latestChapterElement.textContent.trim()
      const chapterNumberMatch = chapterText.match(/(\d+(\.\d+)?)/)

      if (title && chapterNumberMatch) {
        const chapterNumber = chapterNumberMatch[0]
        const searchButton = document.createElement("button")
        searchButton.textContent = "🔍"
        searchButton.title = "Search for latest chapter"
        searchButton.className = "latest-chapter-search-btn"

        Object.assign(searchButton.style, {
          backgroundColor: "#222222",
          color: "#e2e8f0",
          border: "1px solid #5a1f78",
          padding: "2px 7px",
          margin: "0 6px 0 2px",
          borderRadius: "6px",
          cursor: "pointer",
          fontSize: "13px",
          fontWeight: "500",
          verticalAlign: "middle",
        })

        searchButton.onmouseover = () => (searchButton.style.backgroundColor = "#913FE2")
        searchButton.onmouseout = () => (searchButton.style.backgroundColor = "#222222")

        searchButton.addEventListener("click", (e) => {
          e.preventDefault()
          const searchQuery = `${title} chapter ${chapterNumber}`
          const searchUrl = `https://www.google.com/search?q=${encodeURIComponent(searchQuery)}`
          window.open(searchUrl, "_blank")
        })

        titleElement.parentElement.insertAdjacentElement("beforebegin", searchButton)
      }
    })
  }

  // --- Main observer logic ---
  const observer = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
      for (const node of mutation.addedNodes) {
        if (node.nodeType === Node.ELEMENT_NODE) {
          applySelectorsToNode(node)
          addSearchButtons(node)
        }
      }
    }
  })

  observer.observe(document.body, {
    childList: true,
    subtree: true,
  })

  // --- Initial run on page load ---
  applySelectorsToNode(document)
  addSearchButtons(document)
})()