Skip to content

Releases: readium/kotlin-toolkit

2.4.0

07 Nov 14:21
011e0d7
Compare
Choose a tag to compare

Resources

Changelog

Added

Navigator

  • The EPUB backgroundColor preference is now available with fixed-layout publications.
  • New EPUBNavigatorFragment.Configuration.useReadiumCssFontSize option to revert to the 2.2.0 strategy for setting the font size of reflowable EPUB publications.
    • The native font size strategy introduced in 2.3.0 uses the Android web view's WebSettings.textZoom property to adjust the font size. 2.2.0 was using Readium CSS's --USER__fontSize variable.
    • WebSettings.textZoom will work with more publications than --USER__fontSize, even the ones poorly authored. However the page width is not adjusted when changing the font size to keep the optimal line length.
  • Scroll mode: jumping between two EPUB resources with a horizontal swipe triggers the Navigator.Listener.onJumpToLocator() callback.
    • This can be used to allow the user to go back to their previous location if they swiped across chapters by mistake.
  • Support for non-linear EPUB resources with an opt-in in reading apps (contributed by @chrfalch in #375 and #376).
    1. Override loading non-linear resources with VisualNavigator.Listener.shouldJumpToLink().
    2. Present a new EpubNavigatorFragment by providing a custom readingOrder with only this resource to the constructor.
  • Added dummy navigator fragment factories to prevent crashes caused by Android restoring the fragments after a process death.
    • To use it, set the dummy fragment factory when you don't have access to the Publication instance. Then, either finish the Activity or pop the fragment from the UI before it resumes.
      override fun onCreate(savedInstanceState: Bundle?) {
          val publication = model.publication ?: run {
              childFragmentManager.fragmentFactory = EpubNavigatorFragment.createDummyFactory()
              super.onCreate(savedInstanceState)
      
              requireActivity().finish()
              // or
              navController?.popBackStack()
      
              return
          }
      
          // Create the real navigator factory as usual...
      }

Streamer

  • The EPUB content iterator now returns audio and video elements.

Changed

Navigator

  • EpubNavigatorFragment.firstVisibleElementLocator() now returns the first block element that is visible on the screen, even if it starts on previous pages.
    • This is used to make sure the user will not miss any context when restoring a TTS session in the middle of a resource.

Fixed

Navigator

  • #360 Fix EPUB JavaScript interface injection when rotating the screen on some devices.

Streamer

  • Fixed issue with the TTS starting from the beginning of the chapter instead of the current position.

2.3.0

28 Dec 12:01
bfc536f
Compare
Choose a tag to compare

Resources

Changelog

Added

Shared

  • Extract the raw content (text, images, etc.) of a publication. Take a look at the user guide.
  • Add support for unsafe HTTP redirections with DefaultHttpClient.
    • You will need to opt-in explicitly by implementing DefaultHttpClient.Callback.onFollowUnsafeRedirect.

Navigator

  • Improved Javascript support in the EPUB navigator:
    • Register custom JavascriptInterface objects to inject native Kotlin code in the EPUB web views.
      EpubNavigatorFragment.createFactory(
          publication = publication,
          …,
          config = EpubNavigatorFragment.Configuration().apply {
              registerJavascriptInterface("customInterface") { link ->
                  MyCustomApi(link)
              }
          }
      )
      
      class MyCustomApi(val link: Link) {
          @JavascriptInterface
          fun api(arg: String): String {
              return "API called from the resource ${link.href} with argument $arg")
          }
      }
    • Evaluate JavaScript on the currently visible HTML resource with EpubNavigatorFragment.evaluateJavascript().
      val result = navigator.evaluateJavascript("customInterface.api('argument')")
  • New PSPDFKit adapter for rendering PDF documents. Take a look at the user guide.
  • A brand new text-to-speech implementation.
  • Support for custom fonts with the EPUB navigator.
  • New EPUB user preferences, as part of the revamped Settings API:
    • backgroundColor - Default page background color.
    • fontWeight - Base text font weight.
    • textColor - Default page text color.
    • textNormalization - Normalize font style, weight and variants, which improves accessibility.
    • imageFilter - Filter applied to images in dark theme (darken, invert colors)
    • language - Language of the publication content.
    • readingProgression - Direction of the reading progression across resources, e.g. RTL.
    • typeScale - Scale applied to all element font sizes.
    • paragraphIndent - Text indentation for paragraphs.
    • paragraphSpacing - Vertical margins for paragraphs.
    • hyphens - Enable hyphenation.
    • ligatures - Enable ligatures in Arabic.
  • Fixed scroll inertia when scrolling an EPUB.
  • EPUB decorations can now be attached to Locator objects containing only an HTML ID (locations.fragments) or a CSS selector (locations.cssSelector).

Changed

Shared

  • TransformingResource now caches its content by default, as it is the correct behavior in most cases. Set cacheBytes = false explicitly to revert to the previous behavior.
  • The previous PDF navigator was extracted in its own package to support third-party PDF engines. This is a breaking change if your app supported PDF, take a look at the migration guide.

Navigator

  • The EPUB and PDF user preferences API got revamped. Take a look at the user guide and the migration guide to learn how to use it.
  • Decoration.extras is now a Map<String, Any> instead of Bundle. You will need to update your app if you were storing custom data in extras, for example:
    val decoration = Decoration(...,
        extras = mapOf("id" to id)
    )
    
    val id = decoration.extras["id"] as? Long

Deprecated

Streamer

Fixed

Streamer

  • Fixed parsing the table of contents of an EPUB 3 using NCX instead of a Navigation Document.

Navigator

  • swift-toolkit#61 Fixed serving EPUB resources when the HREF contains an anchor or query parameters.
  • Fixed emitting currentLocator with fixed layout EPUBs.
  • Prevent refreshing an already loaded EPUB resource when jumping to a Locator in it.
  • #86 Fixed page swipes while selecting text in an EPUB resource.
  • The onTap event is not sent when an EPUB text selection is active anymore, to prevent showing the app bar while dismissing a selection.
  • #76 Fixed EPUB fixed layout font size affected by device settings.
  • Decoration objects are now properly comparable with equals().
  • #292 Fix broken pagination when an EPUB uses overflow-x: hidden.

2.2.1

24 Oct 15:22
7073077
Compare
Choose a tag to compare

Resources

Changelog

Fixed

Streamer

  • #286 Fixed broken dependency to NanoHTTPD.

Migration Guide

This hotfix release fixes an issue pulling a third-party dependency (NanoHTTPD) from JitPack.

After upgrading, make sure to remove the dependency to NanoHTTPD from your app's build.gradle file before building:

-implementation("com.github.edrlab.nanohttpd:nanohttpd:master-SNAPSHOT") {
-    exclude(group = "org.parboiled")
-}
-implementation("com.github.edrlab.nanohttpd:nanohttpd-nanolets:master-SNAPSHOT") {
-    exclude(group = "org.parboiled")
-}

☝️ If you are stuck with an older version of Readium, you can use this workaround in your root build.gradle, as an alternative.

2.2.0

22 Apr 15:09
Compare
Choose a tag to compare

Resources

Changelog

Added

Shared

  • A new Publication.conformsTo() API to identify the profile of a publication.
  • Support for the conformsTo RWPM metadata, to identify the profile of a Publication.

Navigator

  • The PDF navigator now honors the publication reading progression with support for right-to-left and horizontal scrolling.
    • The default (auto) reading progression for PDF is top-to-bottom, which is vertical scrolling.
  • A new convenience utility EdgeTapNavigation to trigger page turns while tapping the screen edges.
    • It takes into account the navigator reading progression to move into the right direction.
    • Call it from the VisualNavigator.Listener.onTap() callback as demonstrated below:
    override fun onTap(point: PointF): Boolean {
        val navigated = edgeTapNavigation.onTap(point, requireView())
        if (!navigated) {
            // Fallback action, for example toggling the app bar.
        }
        return true
    }
  • The new Navigator.Listener.onJumpToLocator() API is called every time the navigator jumps to an explicit location, which might break the linear reading progression.
    • For example, it is called when clicking on internal links or programmatically calling Navigator.go(), but not when turning pages.
    • You can use this callback to implement a navigation history by differentiating between continuous and discontinuous moves.
  • You can now disable the display cutouts padding in the EPUB navigator (contributed by @szymn).
    • This is useful when the navigator is not laid out full screen.
  • (experimental) A new audiobook navigator based on Jetpack media2.
    • See the pull request #80 for the differences with the previous audiobook navigator.
    • This navigator is located in its own module readium-navigator-media2. You will need to add it to your dependencies to use it.
    • The Test App demonstrates how to use the new audiobook navigator, see MediaService and AudioReaderFragment.
  • (experimental) The EPUB navigator now supports overridable drag gestures. See VisualNavigator.Listener.

Deprecated

Shared

  • Publication.type is now deprecated in favor of the new Publication.conformsTo() API which is more accurate.
    • For example, replace publication.type == Publication.TYPE.EPUB with publication.conformsTo(Publication.Profile.EPUB) before opening a publication with the EpubNavigatorFragment.
  • Link.toLocator() is deprecated as it may create an incorrect Locator if the link type is missing.
    • Use publication.locatorFromLink() instead.

Fixed

  • Fix building with Kotlin 1.6.

Streamer

  • Fixed the rendering of PDF covers in some edge cases.
  • Fixed reading ranges of obfuscated EPUB resources.

Navigator

  • Fixed turning pages of an EPUB reflowable resource with an odd number of columns. A virtual blank trailing column is appended to the resource when displayed as two columns.
  • EPUB: Fallback on reflowable if the presentation.layout hint is missing from a manifest.
  • EPUB: Offset of the current selection's rect to take into account the vertical padding.
  • Improve backward compatibility of JavaScript files using Babel.
  • #193 Fixed invisible <audio> elements.

2.1.1

27 Oct 13:18
7d3a792
Compare
Choose a tag to compare

Resources

Changelog

Changed

Navigator

  • Improve loading of EPUB reflowable resources.
    • Resources are hidden until fully loaded and positioned.
    • Intermediary locators are not broadcasted as currentLocator anymore while loading a resource.
    • Improved accuracy when jumping to the middle of a large resource.
    • EpubNavigatorFragment.PaginationListener.onPageLoaded() is now called only a single time, for the currently visible page.
    • VisualNavigator.Listener.onTap() is called even when a resource is not fully loaded.

Fixed

Navigator

  • EpubNavigatorFragment's goForward() and goBackward() are now jumping to the previous or next pages instead of resources.
  • #20 EPUB navigator stuck between two pages with vertical swipes.
  • #27 Internal links break the EPUB navigator (contributed by @mihai-wolfpack).

2.1.0

24 Sep 17:11
b33a5dd
Compare
Choose a tag to compare

Take a look at the migration guide

Added

Shared

  • (alpha) A new Publication SearchService to search through the resources' content, with a default implementation StringSearchService.
  • ContentProtection.Scheme can be used to identify protection technologies using unique URI identifiers.
  • Link objects from archive-based publication assets (e.g. an EPUB/ZIP) have additional properties for entry metadata.
    "properties" {
        "archive": {
            "entryLength": 8273,
            "isEntryCompressed": true
        }
    }

Streamer

  • EPUB publications implement a SearchService to search through the content.
  • Known DRM schemes (LCP and Adobe ADEPT) are now sniffed by the Streamer, when no registered ContentProtection supports them.
    • This is helpful to present an error message when the user attempts to open a protected publication not supported by the app.

Navigator

  • The EPUB navigator is now able to navigate to a Locator using its text context. This is useful for search results or highlights missing precise locations.
  • Get or clear the current user selection of the navigators implementing SelectableNavigator.
  • (alpha) Support for the Decorator API to draw user interface elements over a publication's content.
    • This can be used to render highlights over a text selection, for example.
    • For now, only the EPUB navigator implements DecorableNavigator, for reflowable publications. You can implement custom decoration styles with HtmlDecorationTemplate.
  • Customize the EPUB selection context menu by providing a custom ActionMode.Callback implementation with EpubNavigatorFragment.Configuration.selectionActionModeCallback.
    • This is an alternative to overriding Activity.onActionModeStarted() which does not seem to work anymore with Android 12.
  • (alpha) A new audiobook navigator based on Android's MediaSession.
    • It supports out-of-the-box media style notifications and background playback.
    • ExoPlayer is used by default for the actual playback, but you can use a custom player by implementing MediaPlayer.

OPDS

  • New APIs using coroutines and R2's HttpClient instead of Fuel and kovenant (contributed by @stevenzeck).

Changed

  • Upgraded to Kotlin 1.5.31 and Gradle 7.1.1

Streamer

  • The default EPUB positions service now uses the archive entry length when available. This is similar to how Adobe RMSDK generates page numbers.
    • To use the former strategy, create the Streamer with: Streamer(parsers = listOf(EpubParser(reflowablePositionsStrategy = OriginalLength(pageLength = 1024))))

Navigator

  • The order of precedence of Locator locations in the reflowable EPUB navigator is: text, HTML ID, then progression. The navigator will now fallback on less precise locations in case of failure.

LCP

  • Migrated to Jetpack Room for the SQLite database storing rights and passphrases (contributed by @stevenzeck).
    • Note that the internal SQL schema changed. You will need to update your app if you were querying the database manually.

Fixed

Shared

  • Crash with HttpRequest.setPostForm() on Android 6.
  • HREF normalization when a resource path contains special characters.

Streamer

  • EPUB style injection when a resource has a <head> tag with attributes.

Navigator

  • When restoring a Locator, The PDF navigator now falls back on locations.position if the page= fragment identifier is missing.

OPDS

  • Links in an OPDS 2 feed are normalized to the feed base URL.