diff --git a/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt b/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt index 9fe1600cdf..359c651945 100644 --- a/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt +++ b/readium/navigator/src/main/java/org/readium/r2/navigator/extensions/Publication.kt @@ -10,10 +10,12 @@ package org.readium.r2.navigator.extensions import kotlinx.coroutines.runBlocking -import org.readium.r2.shared.InternalReadiumApi +import org.readium.r2.shared.DelicateReadiumApi import org.readium.r2.shared.publication.Locator import org.readium.r2.shared.publication.Publication +import org.readium.r2.shared.publication.UrlHref import org.readium.r2.shared.publication.services.positions +import org.readium.r2.shared.util.AbsoluteUrl import org.readium.r2.shared.util.Url // These extensions will be removed in the next release, with `PositionsService`. @@ -22,18 +24,29 @@ internal val Publication.positionsByResource: Map> get() = runBlocking { positions().groupBy { it.href } } /** - * Historically, we used to have "absolute" HREFs starting with a `/` in the manifest for packaged - * publications. We removed the root prefix, but we still need to support the locators created with - * the old HREFs. + * Historically, we used to have "absolute" HREFs in the manifest: + * - starting with a `/` for packaged publications. + * - resolved to the `self` link for remote publications. + * + * We removed the normalization and now use relative HREFs everywhere, but we still need to support + * the locators created with the old absolute HREFs. */ -@InternalReadiumApi +@DelicateReadiumApi public fun Publication.normalizeLocator(locator: Locator): Locator { - if (linkWithRel("self") != null) { - return locator - } + val self = (linkWithRel("self")?.href as? UrlHref)?.url as? AbsoluteUrl - return locator.copy( - href = Url(locator.href.toString().removePrefix("/")) - ?: return locator - ) + return if (self == null) { // Packaged publication + locator.copy( + href = Url(locator.href.toString().removePrefix("/")) + ?: return locator + ) + } else { // Remote publication + // Check that the locator HREF relative to `self` exists int he manifest. + val relativeHref = self.relativize(locator.href) + if (linkWithHref(relativeHref) != null) { + locator.copy(href = relativeHref) + } else { + locator + } + } }