Skip to content

Allow custom JavaScript interfaces in the reflowable Web navigator - #831

Closed
aiviapp wants to merge 1 commit into
readium:developfrom
aiviapp:javascript-interfaces-web-navigator
Closed

aiviapp wants to merge 1 commit into
readium:developfrom
aiviapp:javascript-interfaces-web-navigator

Conversation

@aiviapp

@aiviapp aiviapp commented Sep 3, 2026

Copy link
Copy Markdown

Closes part of #830.

Problem

The new Compose Web navigators give an app no way to reach the WebView they render into, so features built on top of the legacy navigator have no path forward. docs/guides/navigator/epub-feature-parity.md already records it:

| Custom JavaScript interfaces | ✅ | ❌ | Legacy registerJavascriptInterface has no equivalent |

Change

Adds ReflowableWebConfiguration.javascriptInterfaces:

ReflowableWebConfiguration(
    javascriptInterfaces = persistentMapOf(
        "MyBridge" to { href -> MyBridge(href) }
    )
)

It mirrors EpubNavigatorFragment.Configuration.registerJavascriptInterface, including the null-to-skip-this-resource semantics, but is keyed by Url rather than Link since the new navigators do not use Link. The interfaces are registered in ReflowableResource, in the same LaunchedEffect where the navigator already attaches GesturesApi, DocumentStateApi and SelectionListenerApi to the resource web view.

JavascriptInterfaceFactory lives in readium-navigator-web-common so the fixed-layout navigator can adopt the same field later.

Notes

  • Configuration only — no behaviour changes for anyone who does not set the new field.
  • The parity table is moved from ❌ to ⚠️ rather than ✅, since FixedWebConfiguration still has no equivalent. Happy to extend this PR to the fixed-layout navigator if you would rather land both together.
  • Verified locally with ./gradlew :readium:navigators:web:readium-navigator-web-reflowable:compileDebugKotlin and ./gradlew ktlintCheck.

Why this matters to us

We maintain a Flutter wrapper around the toolkit for a reading app whose text-to-speech is generated outside Readium. On the legacy navigator we use registerJavascriptInterface for a bridge that reports image taps and narration sync back from injected JS. The new reflowable navigator is attractive to us for continuous scrolling across resources, which the legacy one cannot do — but without an extension point on the web view, migrating would mean dropping features we ship today. #830 lists the other three gaps we hit; this is the one small enough to send as a patch.

🤖 Generated with Claude Code

The new Compose Web navigators have no way to reach the WebView they render
into, so an app cannot build on top of them the way it can on the legacy
navigator. `docs/guides/navigator/epub-feature-parity.md` records this as
"Custom JavaScript interfaces: legacy yes, new no, `registerJavascriptInterface`
has no equivalent".

Add `ReflowableWebConfiguration.javascriptInterfaces`, mirroring
`EpubNavigatorFragment.Configuration.registerJavascriptInterface` including its
`null`-to-skip-this-resource semantics, but keyed by `Url` since the new
navigators do not use `Link`. The interfaces are registered where the navigator
already attaches its own JS APIs to the resource web view.

Refs readium#830

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@aiviapp aiviapp closed this Sep 3, 2026
@aiviapp
aiviapp force-pushed the javascript-interfaces-web-navigator branch from f50d12c to f4c9ce2 Compare September 3, 2026 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant