Skip to content

fix: properly scroll vertical text #656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 20, 2025

Conversation

shovel-kun
Copy link
Contributor

Fixes scrolling vertical RTL epubs. See before and after video.

EPUB used in demo: https://www.gutenberg.org/ebooks/31617

BEFORE
before.mp4
AFTER
after.webm

@mickael-menu mickael-menu requested a review from Copilot May 15, 2025 09:24
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes the scrolling issue for vertical RTL EPUBs by introducing overscroll detection in the WebView and adjusting scrolling logic in JavaScript for vertical writing mode.

  • Introduces a new overscroll mode in the WebView to determine the proper scroll direction.
  • Adds a new utility function to detect vertical writing mode and adjusts the scroll behavior accordingly in JavaScript.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt Adds overscroll mode detection and updates touch event handling for scrolling.
readium/navigator/src/main/assets/_scripts/src/utils.js Introduces vertical writing mode detection and adjusts scroll-to-start/end logic accordingly.
Comments suppressed due to low confidence (1)

readium/navigator/src/main/java/org/readium/r2/navigator/R2WebView.kt:749

  • [nitpick] Consider extracting the magic number '200' into a well-named constant to clarify its purpose and improve maintainability.
if (abs(totalDelta) < 200) {

Copy link
Member

@mickael-menu mickael-menu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @shovel-kun!

It's looking great in vertical RTL mode, but I noticed a regression in LTR vertical. When going backward to the previous chapter, it's scrolled to the top instead of the bottom/end. Would you mind taking a look? Thank you.

I also simplified a bit the JS conditionals but the issue was there before.

@shovel-kun
Copy link
Contributor Author

@mickael-menu Thanks for reviewing my PR!

I also discovered that currentLocator do not update on scroll in vertical RTL mode, so I'll have to fix that too in addition to the issue you mentioned.

@mickael-menu
Copy link
Member

Ha yes, I had this issue on my radar but I haven't had the time to address it yet. I appreciate your willingness to take a look!

@shovel-kun
Copy link
Contributor Author

Hi @mickael-menu, I fixed the regression for LTR vertical.

However, I notice that the writing-mode will always be vertical-rl in LTR, when it should be vertical-lr (tested on JP epub and EN epub) The cause is this line in ReadiumCSS-pagination-vertical.css.

I'd like your advice on how to resolve this issue, since I'm unfamiliar with how Readium handles stylesheets.

@mickael-menu
Copy link
Member

Thank you,

Could you open an issue on https://github.com/readium/css for this other issue? Jiminy should help you out and then we can import the fixed stylesheets in the toolkit.

@shovel-kun
Copy link
Contributor Author

shovel-kun commented May 17, 2025

@mickael-menu Will do!

By the way, are you sure the issue you described before is a regression? I am able to replicate it on develop

Steps to reproduce:

  1. In TestApp, open an Epub.
  2. Enable scroll LTR.
  3. Scroll and confirm it pages correctly.
  4. Change to scroll RTL
  5. It does not page correctly

The issue is caused by the SimpleOnPageChangeListener not being readded to resourcePager when resourcePager is invalidated.

I've patched this by creating a private member var to store pageChangeListener, and readding the listener on every invalidation.

Shall I open a new PR or should I include the patch in this PR?

Subject: [PATCH] stash
---
Index: readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt
--- a/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt	(revision c1f62fe5aa4170bf59d82b636f324f167b6a0548)
+++ b/readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt	(date 1747465013631)
@@ -285,6 +286,8 @@
 
     private var state: State = State.Initializing
 
+    private var pageChangeListener: ViewPager.OnPageChangeListener? = null
+
     // Configurable
 
     override val settings: StateFlow<EpubSettings> get() = viewModel.settings
@@ -412,7 +415,7 @@
         resourcePager = binding.resourcePager
         resetResourcePager()
 
-        resourcePager.addOnPageChangeListener(object : ViewPager.SimpleOnPageChangeListener() {
+        pageChangeListener = object : ViewPager.SimpleOnPageChangeListener() {
 
             override fun onPageSelected(position: Int) {
 //                if (viewModel.layout == EpubLayout.REFLOWABLE) {
@@ -422,6 +425,7 @@
                     if (viewModel.isScrollEnabled.value) {
                         if (currentPagerPosition < position) {
                             // handle swipe LEFT
                             webView.scrollToStart()
                         } else if (currentPagerPosition > position) {
                             // handle swipe RIGHT
@@ -430,6 +434,7 @@
                     } else {
                         if (currentPagerPosition < position) {
                             // handle swipe LEFT
                             webView.setCurrentItem(0, false)
                         } else if (currentPagerPosition > position) {
                             // handle swipe RIGHT
@@ -441,7 +446,10 @@
 
                 notifyCurrentLocation()
             }
-        })
+        }
+
+        // should we throw if not found?
+        pageChangeListener?.let { resourcePager.addOnPageChangeListener(it) }
 
         // Fixed layout publications cannot intercept JS events yet.
         if (publication.metadata.presentation.layout == EpubLayout.FIXED) {
@@ -554,7 +562,9 @@
 
     private fun invalidateResourcePager() {
         val locator = currentLocator.value
+        val listener = pageChangeListener
         resetResourcePager()
+        listener?.let { resourcePager.addOnPageChangeListener(it) }
         go(locator)
     }
 

@mickael-menu
Copy link
Member

You're right, it looks like the issue only happened after changing the scroll or reading progression preference in the same reading session. Nice catch! Feel free to add your patch to this PR. I'll review the whole PR again next week. Thanks again!

@shovel-kun
Copy link
Contributor Author

Fixed progression not updating on scroll in Vertical Text mode.

Vertical LTR chapter paging is still broken, since I am unable to get the user's desired ReadingProgression from native to webview. The properties dir and writing-mode are unreliable because dir has been forbidden from applying in vertical text, and writing-mode is always vertical-rl in the CJK vertical text stylesheet. I am waiting for readium/css#180 to be resolved in order to fix this.

I also noticed that highlighting in vertical text is broken (the decorations rectangle are incorrectly positioned). I might try and tackle this too, unless there other considerations?

@mickael-menu mickael-menu requested a review from Copilot May 20, 2025 09:59
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes vertical text scrolling in EPUBs with right‐to‐left reading progression by propagating vertical text settings across the navigator components and adjusting overscroll and progression calculations accordingly.

  • Added a verticalText property in the view model and propagated it to the fragment and web views.
  • Updated scroll and progression logic in R2WebView.kt, R2BasicWebView.kt, and utils.js to handle vertical writing modes.
  • Updated CHANGELOG.md to reflect the fixes.

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
EpubNavigatorViewModel.kt Added verticalText getter to expose vertical text setting.
EpubNavigatorFragment.kt Introduced pageChangeListener variable and propagated verticalText to the layout.
R2WebView.kt Implemented overscroll mode logic and adjusted scrolling behavior for vertical text.
R2BasicWebView.kt Updated progression calculation to handle vertical text scrolling.
utils.js Added vertical writing mode detection and adjusted scroll position calculations accordingly.
CHANGELOG.md Documented the vertical text scrolling fixes.

Copy link
Member

@mickael-menu mickael-menu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this is very helpful!

Vertical LTR chapter paging is still broken, since I am unable to get the user's desired ReadingProgression from native to webview. The properties dir and writing-mode are unreliable because dir has been forbidden from applying in vertical text, and writing-mode is always vertical-rl in the CJK vertical text stylesheet. I am waiting for readium/css#180 to be resolved in order to fix this.

Yeah I think we should just disable LTR reading progression when vertical = true for now, until we upgrade to Readium CSS and the option is available.

I also noticed that highlighting in vertical text is broken (the decorations rectangle are incorrectly positioned). I might try and tackle this too, unless there other considerations?

No feel free to contribute the fix if you need. We don't have anyone on our team experienced in vertical reading, so proper feedback from implementers is very helpful.

Thanks again.

@mickael-menu mickael-menu merged commit e5f5ad1 into readium:develop May 20, 2025
4 checks passed
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.

2 participants