Japscan: fix chapter list - #18111
Open
QuentinVdr wants to merge 9 commits into
Open
Conversation
Starmania
added a commit
to Starmania/extensions-source
that referenced
this pull request
Aug 11, 2026
Addresses the review findings on keiyoushi#18111. The first two are the blockers that made the reader fail on the captcha path; the rest are robustness items from the same review. Blockers: - Wait for the reader to mount before claiming the capture run. onPageFinished fires on the bare document when the WebView HTTP cache is warm — which it is after a long captcha solve — so the driver started before any reader script had run, found no #d-img containers, took the MISMATCH branch and called passDone(). That returned an empty page list reported as a successful load, and __japscanDriverStarted then locked out the real load when the reader did mount. Both drivers now poll for the reader DOM and only take the claim once it is there, standing down for a later fire otherwise. MISMATCH no longer calls passDone(), so a genuine mismatch surfaces as an error instead of a blank chapter. - Start the idle watchdog after the captcha phase. lastActivity was stamped when JsInterface was constructed, before a captcha wait that can run to CF_MAX_POLLS * CF_POLL_INTERVAL_MS. The watchdog's first check therefore saw captchaPhase + 15s of "inactivity" against a 45s budget with nothing captured yet, aborting healthy runs whenever the solve took over ~30s. Also: - Constrain the page-cache interceptor to our own spool files. It read any absolute path handed to it under the sentinel host; these URLs are persisted with the page and outlive the run that produced them. - Sniff PNG vs JPEG instead of always reporting image/jpeg: only the webtoon driver re-encodes, the paginated one stores the descrambler's blob as-is. - Derive the WebView host allowlist from the base URL rather than hardcoding japscan.foo, which is already one rotation behind. - Derive internalBaseUrl from baseUrl instead of repeating the origin as a second literal, so a domain rotation only has to touch build.gradle.kts. baseUrl itself still points at the popular listing, which is deliberate. - Drop the "longest slug wins" chapter URL fallback. It fired exactly when the slug/number binding rejected every candidate, which is when a honeypot is the likely sole survivor. - Give the spool a size ceiling as well as an age cutoff. One chapter measured 111 files / 12.4 MB and nothing was freed on read. - Include the per-call random id in the spool session tag: the reader preloads the next chapter, so two captures starting in the same millisecond overwrote each other's tiles. - Keep a partial capture instead of discarding it when the run ends on a timeout, and fail with a clear message when nothing was captured at all. - Don't fail the chapter if dismissing the captcha WebView throws; the captcha is already solved by that point.
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
honeypot rows are rejected by hidden-style detection + slug/number binding. Pages are captured by loading the chapter in a detached WebView, letting the site's descrambler run, and reading the painted canvases — one driver for paginated (manga/bd/comic), one for webtoon (manhwa/manhua). Captures are spooled to cacheDir and served via an interceptor rather than held in memory.
Two things worth flagging:
WebViewinstead ofrunWebView, which fixes the viewport to device metrics — the webtoon driver needs a forced 1920px viewport or the reader only renders one tile per page. Same pattern as the mergedComikeyextension. Can add a viewport option to core/WebView.kt as a follow-up.Closes : #17479 & #17968
Checklist:
versionCodevalue inbuild.gradle.ktsbaseVersionCodeinbuild.gradle.kts(if updated multisrc theme code)contentWarningconfiguration inbuild.gradle.ktsappropriatelyidif a source's name or language were changedweb_hi_res_512.pngwhen adding a new extension