1
Userscript
Sulthan Zaki edited this page 2026-07-26 20:39:31 +07:00

Userscript

Single file: userscript/manga-bookmark.user.js. One IIFE, no GM_* APIs, so it runs unchanged in Bromite's native engine and in desktop Tampermonkey/Violentmonkey for fast iteration.

Structure

  1. Site adapters — one per host. detect(location, document) returns page type + IDs, keyed off URL regex (most stable signal). title/cover come from og:title/og:image meta tags, not CSS classes.
  2. API client — apiGet/apiPut/apiDelete with bearer header. localStorage key mangabm:cache gives instant render + offline fallback.
  3. Progress logic — auto-upserts last_chapter only when chapterNum >= stored last_chapter_num (re-reading old chapters never regresses progress; an unparseable number just sets the current chapter). Manual panel override forces any value regardless.
  4. UI — rendered inside a Shadow DOM root, isolating it from site CSS (critical on mobile where site styles are unpredictable).
  5. SPA navigation — Asura is Astro, client-routed on comic/chapter pages: the script patches history.pushState/replaceState and listens popstate, re-running detect() on URL change so auto-update fires without a full reload. Demonic does classic reloads, so an initial document-idle run is enough there.

Config

Edit the block at the top of the file:

const API_BASE = "https://manga-api.<domain>"; // no trailing slash
const API_TOKEN = "<same token as backend's API_TOKEN>";

The token lives in the userscript's isolated world — the manga sites' own JS cannot read it.

Site adapter reference (verified live 2026-07-24)

Site Series URL Chapter URL series_id
Asura (asurascans.com) /comics/<slug-hash> /comics/<slug-hash>/chapter/<n> <slug-hash>
Demonic (demonicscans.org) /manga/<slug> /title/<slug>/chapter/<n>/<page> (chaptered.php?manga=<id>&chapter=<n> 301s here) <slug>

Notes:

  • asuracomic.net deep links 301 to the root of asurascans.com, discarding the path — dead end, use asurascans.com directly. The host stays in @match in case the redirect starts preserving paths again.
  • Asura og:title has a Chapter N - Read Online | Asura Scans suffix the adapter strips; Demonic chapter og:title is <Title> Chapter N.
  • Demonic's <slug> is identical on /manga/… and the canonical /title/… reader, so a bookmark set from the series page and an auto-update from the reader resolve to the same key.
  • If either site changes its URL shape, update the regex in that site's adapter and re-verify against a live page before trusting it.

Install on Bromite (mobile)

  1. Bromite → Settings → User scripts → enable (accept the permission prompt).
  2. Save the configured manga-bookmark.user.js to the device (or open its raw URL) — Bromite detects .user.js and offers to install.
  3. Confirm install; the @match list covers both sites.
  4. Open a series on either site — a 📑 button appears bottom-right.

Menu wording varies by Bromite build. If "User scripts" is absent, update Bromite or use a build that has it.

Day-to-day use

  • Bookmark: panel → + Bookmark this.
  • Auto-progress: opening a chapter of a bookmarked series records it when the chapter number is ≥ the stored one.
  • Manual override: panel → Edit on any row forces a specific chapter.
  • Continue: jumps to the last-read chapter (or the series page).
  • Latest chapter: rows show Read: … · Latest: … once the newest published chapter is known and ahead of your progress.
  • Favourites: ☆ toggles per row; ★ Favourites tab narrows the list. Favourited series still show under All. The flag syncs across devices; the chosen tab does not.
  • Bookmarks made on one site appear when the panel opens on the other — the backend is the shared store.
  • Neither favouriting nor a newly-learned chapter reorders the list — only reading progress does (see Backend-API).
  • Offline / backend down: changes cache in localStorage, retried on the next successful load (last-write-wins).

How "latest chapter" is found

Only a series page lists every chapter; the backend can't fetch either site itself (Cloudflare blocks server-side requests, no API/feed exists). So the userscript does the looking, from your own browser session:

  • Opening a bookmarked series page records its newest chapter directly.
  • Otherwise it background-fetches series pages — same-origin only, so browsing Asura refreshes Asura bookmarks and vice versa. At most one series check per navigation, at most one check per series every 4 hours (LATEST_CHECK_BATCH / LATEST_CHECK_THROTTLE_MS). Failures are silent, retried after the window.

Freshness (mangabm:lastchecked in localStorage) is per-device and deliberately not synced — each device checks on its own. The backend also runs its own independent poller (see Backend-API) so latest_chapter stays fresh even when you aren't browsing.