Skip to content

Commit 35b3fa2

Browse files
Support for EPUB internal links (#28)
1 parent 278931f commit 35b3fa2

File tree

3 files changed

+43
-26
lines changed

3 files changed

+43
-26
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ All notable changes to this project will be documented in this file. Take a look
2222
#### Navigator
2323

2424
* `EpubNavigatorFragment`'s `goForward()` and `goBackward()` are now jumping to the previous or next pages instead of resources.
25-
* [#20](https://github.com/readium/kotlin-toolkit/issues/20) EPUB navigator stuck between two pages with vertical swipes
25+
* [#20](https://github.com/readium/kotlin-toolkit/issues/20) EPUB navigator stuck between two pages with vertical swipes.
26+
* [#27](https://github.com/readium/kotlin-toolkit/issues/27) Internal links break the EPUB navigator (contributed by [@mihai-wolfpack](https://github.com/readium/kotlin-toolkit/pull/28)).
2627

2728

2829
## [2.1.0]

readium/navigator/src/main/java/org/readium/r2/navigator/R2BasicWebView.kt

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
6565
* Returns the custom [ActionMode.Callback] to be used with the text selection menu.
6666
*/
6767
val selectionActionModeCallback: ActionMode.Callback? get() = null
68+
69+
/**
70+
* Offers an opportunity to override a request loaded by the given web view.
71+
*/
72+
fun shouldOverrideUrlLoading(webView: WebView, request: WebResourceRequest): Boolean = false
6873
}
6974

7075
lateinit var listener: Listener
@@ -471,31 +476,10 @@ open class R2BasicWebView(context: Context, attrs: AttributeSet) : WebView(conte
471476
}
472477
}
473478

474-
/**
475-
* Prevents opening external links in the web view.
476-
* To be called from the WebViewClient implementation attached to the web view.
477-
*/
478479
internal fun shouldOverrideUrlLoading(request: WebResourceRequest): Boolean {
479-
val resourceUrl = url ?: return false
480-
481-
// List of hosts that are allowed to be loaded in the web view.
482-
// The host of the page already loaded in the web view is always allowed.
483-
val passthroughHosts = listOfNotNull(
484-
"localhost", "127.0.0.1",
485-
tryOrNull { Uri.parse(resourceUrl) }?.host
486-
)
487-
if (!passthroughHosts.contains(request.url.host)) {
488-
openExternalLink(request.url)
489-
return true
490-
}
491-
492-
return false
493-
}
480+
if (resourceUrl == request.url?.toString()) return false
494481

495-
private fun openExternalLink(url: Uri) {
496-
CustomTabsIntent.Builder()
497-
.build()
498-
.launchUrl(context, url)
482+
return listener.shouldOverrideUrlLoading(this, request)
499483
}
500484

501485
// Text selection ActionMode overrides

readium/navigator/src/main/java/org/readium/r2/navigator/epub/EpubNavigatorFragment.kt

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@ import android.content.Context
1010
import android.content.SharedPreferences
1111
import android.graphics.PointF
1212
import android.graphics.RectF
13+
import android.net.Uri
1314
import android.os.Bundle
1415
import android.view.ActionMode
1516
import android.view.LayoutInflater
1617
import android.view.View
1718
import android.view.ViewGroup
19+
import android.webkit.WebResourceRequest
20+
import android.webkit.WebView
21+
import androidx.browser.customtabs.CustomTabsIntent
1822
import androidx.collection.forEach
1923
import androidx.fragment.app.Fragment
2024
import androidx.fragment.app.FragmentActivity
@@ -46,7 +50,6 @@ import org.readium.r2.shared.publication.*
4650
import org.readium.r2.shared.publication.epub.EpubLayout
4751
import org.readium.r2.shared.publication.presentation.presentation
4852
import org.readium.r2.shared.publication.services.isRestricted
49-
import org.readium.r2.shared.publication.services.positions
5053
import org.readium.r2.shared.publication.services.positionsByReadingOrder
5154
import kotlin.math.ceil
5255
import kotlin.reflect.KClass
@@ -262,7 +265,6 @@ class EpubNavigatorFragment private constructor(
262265
internal var pendingLocator: Locator? = null
263266

264267
override fun go(locator: Locator, animated: Boolean, completion: () -> Unit): Boolean {
265-
266268
val href = locator.href
267269
// Remove anchor
268270
.substringBefore("#")
@@ -470,6 +472,36 @@ class EpubNavigatorFragment private constructor(
470472

471473
override val selectionActionModeCallback: ActionMode.Callback?
472474
get() = config.selectionActionModeCallback
475+
476+
/**
477+
* Prevents opening external links in the web view and handles internal links.
478+
*/
479+
override fun shouldOverrideUrlLoading(webView: WebView, request: WebResourceRequest): Boolean {
480+
val url = request.url?.toString()
481+
?: return false
482+
483+
val baseUrl = baseUrl.takeIf { it.isNotBlank() }
484+
?: publication.linkWithRel("self")?.href
485+
?: return false
486+
487+
if (!url.startsWith(baseUrl)) {
488+
openExternalLink(request.url)
489+
} else {
490+
// Navigate to an internal link
491+
go(Link(href = url.removePrefix(baseUrl).addPrefix("/")))
492+
}
493+
494+
return true
495+
}
496+
497+
private fun openExternalLink(url: Uri) {
498+
val context = context ?: return
499+
tryOrLog {
500+
CustomTabsIntent.Builder()
501+
.build()
502+
.launchUrl(context, url)
503+
}
504+
}
473505
}
474506

475507
override fun goForward(animated: Boolean, completion: () -> Unit): Boolean {

0 commit comments

Comments
 (0)