Skip to content
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
b02a42d
Update dependencies
qnga Nov 25, 2025
9cf2721
Introduce HtmlId and cosmetic changes
qnga Nov 25, 2025
9546527
Downgrade kotlinx-serialization
qnga Nov 26, 2025
c6be690
Fix go to URL with fragment
qnga Nov 26, 2025
1497d47
Implement positions and total progression
qnga Nov 27, 2025
be1d542
Merge branch 'develop' of github.com:readium/kotlin-toolkit into navi…
qnga Nov 27, 2025
8eb687a
Fix location reporting
qnga Nov 27, 2025
52ec6f9
Fix moveToProgression in WebViewScrollController
qnga Dec 2, 2025
83b3420
Typo
qnga Dec 2, 2025
8646fc2
Fix going to initial progression
qnga Dec 2, 2025
6937581
Various fixes
qnga Dec 2, 2025
737affc
Simplify uses of callbacks on WebView ready
qnga Dec 2, 2025
1214658
Fix progression restoration and add viewport
qnga Dec 4, 2025
ba9ee67
Add viewport and refactor go
qnga Dec 6, 2025
5046ffe
Fix various bugs
qnga Dec 7, 2025
69d9678
Merge branch 'develop' of github.com:readium/kotlin-toolkit into navi…
qnga Dec 12, 2025
bb84f96
Don't turn page on tap when there is a selection ongoing
qnga Dec 14, 2025
247b861
Fix insets management in paginated mode
qnga Dec 15, 2025
fcad96b
Fix background update on FXL
qnga Dec 20, 2025
9f7aba4
Fix FontFamiliy Declarations
qnga Jan 4, 2026
ccbb3bb
Fix margins when reflowable content is zoomed out.
qnga Jan 6, 2026
ab79c18
Fix N columns mode, make margin cover insets
qnga Jan 12, 2026
e363488
Fixt crash on orientation change in FXL
qnga Jan 12, 2026
63b3390
Fix crash on layout change
qnga Jan 14, 2026
d75f309
Remove node_modules
qnga Jan 14, 2026
a561408
Fix location priority in go
qnga Jan 14, 2026
638692f
Remove package.json
qnga Jan 14, 2026
751831d
Improvements and cosmetic changes in FXL, rationalize dependencies
qnga Jan 14, 2026
84b95c4
Remove decoration group when it's missing in the new submitted decora…
qnga Jan 15, 2026
9e54f23
Fix single highlight ID for everyone in demo
qnga Jan 15, 2026
06367cc
Merge branch 'develop' of github.com:readium/kotlin-toolkit into navi…
qnga Jan 15, 2026
294be29
Cosmetic changes in FXL
qnga Jan 15, 2026
c8bb665
Fix possible race condition in selection in FXL
qnga Jan 15, 2026
0dccaf3
Use lineLength in scroll mode
qnga Jan 16, 2026
03ebc98
Update Readium CSS
qnga Jan 16, 2026
16ca596
Revisit margins and insets
qnga Jan 16, 2026
48506db
Fix again crash on change in spread setting
qnga Jan 16, 2026
583d0ad
Adjust selection iframe rect to parent in single spread FXL
qnga Jan 19, 2026
fde41ce
Fix go method calls never resuming
qnga Jan 20, 2026
6412636
Revert moving scrollStates to state in FXL, fix inconsistent scroll d…
qnga Jan 20, 2026
e7cc507
New attempt to fix the crash
qnga Jan 21, 2026
f329858
Fix
qnga Jan 21, 2026
36626fb
Recreate pagerState when spreads setting changes.
qnga Jan 22, 2026
c82af32
Do not call both onTap and onLinkActivated
qnga Jan 23, 2026
b1bba9c
Fix #745 to enable update to Compose 1.10
qnga Jan 30, 2026
e8244de
Merge branch 'develop' of github.com:readium/kotlin-toolkit into navi…
qnga Jan 30, 2026
8fec056
Introduce owned MutatorMutex in navigation delegates
qnga Feb 2, 2026
30ef220
Fix bug
qnga Feb 3, 2026
5ce1eed
Downgrade to Compose 1.9.5
qnga Feb 3, 2026
d1c267f
Various changes
qnga Feb 4, 2026
68b8360
Complete update to Compose 1.10
qnga Feb 6, 2026
428d3e5
Rethrow CancellationException
qnga Feb 6, 2026
5ccca9f
Remove useless dependencies
qnga Feb 6, 2026
db77e62
Merge branch 'develop' into navigator2-improvements
qnga Feb 6, 2026
573072d
Fix missing headers
qnga Feb 6, 2026
5c486a2
Cosmetic changes
qnga Feb 6, 2026
e98a939
Add safeguards inspired by fixed layout misfortune on reflowable
qnga Feb 6, 2026
d9ea5f9
Small fixes
qnga Feb 6, 2026
8282dd2
Remove log
qnga Feb 6, 2026
bcf425d
Small fixes
qnga Feb 9, 2026
ff9ea0f
Small location-related fixes
qnga Feb 10, 2026
7f290d3
Merge branch 'develop' into navigator2-improvements
qnga Feb 10, 2026
2e42f61
Merge branch 'navigator2-improvements' of github.com:readium/kotlin-t…
qnga Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sealed class HighlightsManager<L : DecorationLocation>(
decorationFactory: (Highlight, Long) -> List<Decoration<L>>,
) {

private val lastHighlightId: Long = -1
private var lastHighlightId: Long = -1

private val highlightsMutable: MutableStateFlow<PersistentMap<Long, Highlight>> =
MutableStateFlow(persistentMapOf())
Expand All @@ -62,7 +62,9 @@ sealed class HighlightsManager<L : DecorationLocation>(
@ColorInt tint: Int,
annotation: String = "",
): Long {
val id = lastHighlightId + 1
lastHighlightId += 1
val id = lastHighlightId

val highlight = Highlight(
locator = locator,
style = style,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import org.readium.r2.shared.util.Language
/**
* Stateful user settings component.
*/

@Composable
fun <P : Preferences<P>, S : Settings, E : PreferencesEditor<P, S>> UserPreferences(
editor: E,
Expand Down
10 changes: 5 additions & 5 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ androidx-annotation = "1.9.1"
androidx-appcompat = "1.7.1"
androidx-browser = "1.9.0"
androidx-cardview = "1.0.0"
androidx-compose-animation = "1.10.0"
androidx-compose-foundation = "1.10.0"
androidx-compose-material = "1.10.0"
androidx-compose-animation = "1.9.5"
androidx-compose-foundation = "1.9.5"
androidx-compose-material = "1.9.5"
androidx-compose-material-icons = "1.7.8"
androidx-compose-material3 = "1.4.0"
androidx-compose-runtime = "1.10.0"
androidx-compose-ui = "1.10.0"
androidx-compose-runtime = "1.9.5"
androidx-compose-ui = "1.9.5"
androidx-constraintlayout = "2.2.1"
androidx-core = "1.17.0"
androidx-datastore = "1.2.0"
Expand Down
8 changes: 8 additions & 0 deletions readium/navigator/src/main/assets/_scripts/src/gestures.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ window.addEventListener("DOMContentLoaded", function () {
});

function onClick(event) {
console.log(
`selectionType ${window.getSelection().type} isCollapsed ${
window.getSelection().isCollapsed
}`
);

if (!window.getSelection().isCollapsed) {
// There's an on-going selection, the tap will dismiss it so we don't forward it.
return;
}

console.log("Reporting tap");

var pixelRatio = window.devicePixelRatio;
let clickEvent = {
defaultPrevented: event.defaultPrevented,
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

package org.readium.r2.navigator.epub.css

import android.net.Uri
import androidx.core.net.toUri
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
Expand Down Expand Up @@ -130,7 +130,7 @@ internal data class ReadiumCss(
if (googleFonts.isNotEmpty()) {
val families = googleFonts.joinToString("|") { it.name }

val uri = Uri.parse("https://fonts.googleapis.com/css")
val uri = "https://fonts.googleapis.com/css".toUri()
.buildUpon()
.appendQueryParameter("family", families)
.build()
Expand Down
6 changes: 3 additions & 3 deletions readium/navigators/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ dependencies {
api(project(":readium:readium-shared"))
api(project(":readium:readium-navigator"))

api(libs.androidx.compose.foundation)
api(libs.kotlinx.coroutines.android)
api(libs.kotlinx.collections.immutable)
api(libs.kotlinx.serialization.json)

implementation(libs.androidx.recyclerview)
implementation(libs.kotlinx.serialization.json)
implementation(libs.bundles.compose)
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.android)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
package org.readium.navigator.common

import org.readium.r2.shared.ExperimentalReadiumApi
import org.readium.r2.shared.publication.Locator

/**
* An HTML Id.
*/
@ExperimentalReadiumApi
@JvmInline
public value class HtmlId(
public val value: String,
)

/**
* A CSS selector.
Expand All @@ -24,7 +34,11 @@ public value class CssSelector(
@JvmInline
public value class Progression private constructor(
public val value: Double,
) {
) : Comparable<Progression> {

override fun compareTo(other: Progression): Int {
return value.compareTo(other.value)
}

public companion object {

Expand All @@ -41,11 +55,16 @@ public value class Progression private constructor(
@JvmInline
public value class Position private constructor(
public val value: Int,
) {
) : Comparable<Position> {

override fun compareTo(other: Position): Int {
return value.compareTo(other.value)
}

public companion object {

public operator fun invoke(value: Double): Position? =
value.takeIf { value >= 0 }
public operator fun invoke(value: Int): Position? =
value.takeIf { value >= 1 }
?.let { Position(it) }
}
}
Expand All @@ -60,3 +79,39 @@ public data class TextQuote(
val prefix: String,
val suffix: String,
)

@ExperimentalReadiumApi
public fun TextQuote.toTextAnchor(end: Boolean = false): TextAnchor =
when (end) {
false -> TextAnchor(
textBefore = prefix,
textAfter = text + suffix
)
true -> TextAnchor(
textBefore = prefix + text,
textAfter = text
)
}

/**
* A [TextAnchor] is a pair of short text snippets allowing to locate in a text.
*/
@ExperimentalReadiumApi
public data class TextAnchor(
val textBefore: String,
val textAfter: String,
)

@ExperimentalReadiumApi
public fun Locator.Text.toTextQuote(): TextQuote? =
highlight?.let { highlight ->
TextQuote(
text = highlight,
prefix = before.orEmpty(),
suffix = after.orEmpty()
)
}

@ExperimentalReadiumApi
public fun Locator.Text.toTextAnchor(end: Boolean = false): TextAnchor? =
toTextQuote()?.toTextAnchor(end)
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,9 @@ public interface PositionLocation : Location {

public val position: Position
}

@ExperimentalReadiumApi
public interface TextAnchorLocation : Location {

public val textAnchor: TextAnchor
}
7 changes: 3 additions & 4 deletions readium/navigators/web/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ dependencies {
api(project(":readium:readium-navigator"))
api(project(":readium:navigators:readium-navigator-common"))

api(libs.androidx.compose.foundation)
api(libs.kotlinx.coroutines.android)
api(libs.kotlinx.collections.immutable)

implementation(libs.kotlinx.serialization.json)
implementation(libs.bundles.compose)
api(libs.kotlinx.serialization.json)
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.android)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

package org.readium.navigator.web.common

import kotlinx.collections.immutable.*
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.serialization.Serializable
import kotlinx.collections.immutable.plus
import kotlinx.collections.immutable.toImmutableList
import org.readium.r2.navigator.preferences.FontFamily
import org.readium.r2.shared.ExperimentalReadiumApi
import org.readium.r2.shared.util.Either
Expand Down Expand Up @@ -214,29 +215,3 @@ public enum class FontWeight(public val value: Int) {
EXTRA_BOLD(800),
BLACK(900),
}

/**
* Typeface for a publication's text.
*
* For a list of vetted font families, see https://readium.org/readium-css/docs/CSS10-libre_fonts.
*/
@ExperimentalReadiumApi
@JvmInline
@Serializable
public value class FontFamily(public val name: String) {

public companion object {
// Generic font families
// See https://www.w3.org/TR/css-fonts-4/#generic-font-families
public val SERIF: FontFamily = FontFamily("serif")
public val SANS_SERIF: FontFamily = FontFamily("sans-serif")
public val CURSIVE: FontFamily = FontFamily("cursive")
public val FANTASY: FontFamily = FontFamily("fantasy")
public val MONOSPACE: FontFamily = FontFamily("monospace")

// Accessibility fonts embedded with Readium
public val ACCESSIBLE_DFA: FontFamily = FontFamily("AccessibleDfA")
public val IA_WRITER_DUOSPACE: FontFamily = FontFamily("IA Writer Duospace")
public val OPEN_DYSLEXIC: FontFamily = FontFamily("OpenDyslexic")
}
}
9 changes: 5 additions & 4 deletions readium/navigators/web/fixedlayout/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ dependencies {
api(project(":readium:navigators:web:readium-navigator-web-common"))
implementation(project(":readium:navigators:web:readium-navigator-web-internals"))

implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.collections.immutable)
implementation(libs.bundles.compose)
api(libs.androidx.compose.foundation)
api(libs.kotlinx.coroutines.android)
api(libs.kotlinx.collections.immutable)
api(libs.kotlinx.serialization.json)

implementation(libs.timber)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.androidx.webkit)
implementation(libs.jsoup)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import org.readium.navigator.common.DecorationLocation
import org.readium.navigator.common.ExportableLocation
import org.readium.navigator.common.GoLocation
import org.readium.navigator.common.Location
import org.readium.navigator.common.Position
import org.readium.navigator.common.PositionLocation
import org.readium.navigator.common.Progression
import org.readium.navigator.common.SelectionLocation
import org.readium.navigator.common.TextQuote
import org.readium.navigator.common.TextQuoteLocation
Expand Down Expand Up @@ -87,26 +90,32 @@ public sealed interface FixedWebDecorationLocation : DecorationLocation {

internal data class FixedWebDecorationCssSelectorLocation(
override val href: Url,
val cssSelector: CssSelector,
) : FixedWebDecorationLocation
override val cssSelector: CssSelector,
) : FixedWebDecorationLocation, CssSelectorLocation

internal data class FixedWebDecorationTextQuoteLocation(
override val href: Url,
val textQuote: TextQuote,
override val textQuote: TextQuote,
val cssSelector: CssSelector?,
) : FixedWebDecorationLocation
) : FixedWebDecorationLocation, TextQuoteLocation

@ExperimentalReadiumApi
@ConsistentCopyVisibility
public data class FixedWebLocation internal constructor(
override val href: Url,
override val position: Position,
val totalProgression: Progression,
private val mediaType: MediaType?,
) : ExportableLocation {
) : ExportableLocation, PositionLocation {

override fun toLocator(): Locator =
Locator(
href = href,
mediaType = mediaType ?: MediaType.XHTML
mediaType = mediaType ?: MediaType.XHTML,
locations = Locator.Locations(
position = position.value,
totalProgression = totalProgression.value
)
)
}

Expand Down
Loading