Skip to content

Commit

Permalink
Optimize scrolling to an EPUB locator with a CSS selector (#435)
Browse files Browse the repository at this point in the history
  • Loading branch information
mickael-menu committed May 22, 2024
1 parent 2fdfea3 commit a3635b5
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 18 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ All notable changes to this project will be documented in this file. Take a look

* Support for standalone audio files and their metadata (contributed by [@domkm](https://github.com/readium/swift-toolkit/pull/414)).


### Changed

The Readium Swift toolkit now requires a minimum of iOS 13.
Expand All @@ -26,6 +25,12 @@ The Readium Swift toolkit now requires a minimum of iOS 13.

* EPUB: The `scroll` preference is now forced to `true` when rendering vertical text (e.g. CJK vertical). [See this discussion for the rationale](https://github.com/readium/swift-toolkit/discussions/370).

### Fixed

#### Navigator

* Optimized scrolling to an EPUB text-based locator if it contains a CSS selector.


## [3.0.0-alpha.1]

Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

20 changes: 10 additions & 10 deletions Sources/Navigator/EPUB/EPUBReflowableSpreadView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,9 @@ final class EPUBReflowableSpreadView: EPUBSpreadView {
case let .locator(locator):
go(to: locator) { _ in completion() }
case .start:
go(toProgression: 0) { _ in completion() }
scroll(toProgression: 0) { _ in completion() }
case .end:
go(toProgression: 1) { _ in completion() }
scroll(toProgression: 1) { _ in completion() }
}
}

Expand All @@ -268,18 +268,18 @@ final class EPUBReflowableSpreadView: EPUBSpreadView {
}

if locator.text.highlight != nil {
go(toText: locator.text, completion: completion)
scroll(toLocator: locator, completion: completion)
// FIXME: find the first fragment matching a tag ID (need a regex)
} else if let id = locator.locations.fragments.first, !id.isEmpty {
go(toTagID: id, completion: completion)
scroll(toTagID: id, completion: completion)
} else {
let progression = locator.locations.progression ?? 0
go(toProgression: progression, completion: completion)
scroll(toProgression: progression, completion: completion)
}
}

/// Scrolls at given progression (from 0.0 to 1.0)
private func go(toProgression progression: Double, completion: @escaping (Bool) -> Void) {
private func scroll(toProgression progression: Double, completion: @escaping (Bool) -> Void) {
guard progression >= 0, progression <= 1 else {
log(.warning, "Scrolling to invalid progression \(progression)")
completion(false)
Expand All @@ -301,7 +301,7 @@ final class EPUBReflowableSpreadView: EPUBSpreadView {
}

/// Scrolls at the tag with ID `tagID`.
private func go(toTagID tagID: String, completion: @escaping (Bool) -> Void) {
private func scroll(toTagID tagID: String, completion: @escaping (Bool) -> Void) {
evaluateScript("readium.scrollToId(\'\(tagID)\');") { result in
switch result {
case let .success(value):
Expand All @@ -314,12 +314,12 @@ final class EPUBReflowableSpreadView: EPUBSpreadView {
}

/// Scrolls at the snippet matching the given text context.
private func go(toText text: Locator.Text, completion: @escaping (Bool) -> Void) {
guard let json = text.jsonString else {
private func scroll(toLocator locator: Locator, completion: @escaping (Bool) -> Void) {
guard let json = locator.jsonString else {
completion(false)
return
}
evaluateScript("readium.scrollToText(\(json));") { result in
evaluateScript("readium.scrollToLocator(\(json));") { result in
switch result {
case let .success(value):
completion((value as? Bool) ?? false)
Expand Down
4 changes: 2 additions & 2 deletions Sources/Navigator/EPUB/Scripts/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
scrollRight,
scrollToId,
scrollToPosition,
scrollToText,
scrollToLocator,
setProperty,
setCSSProperties,
} from "./utils";
Expand All @@ -26,7 +26,7 @@ global.readium = {
// utils
scrollToId: scrollToId,
scrollToPosition: scrollToPosition,
scrollToText: scrollToText,
scrollToLocator: scrollToLocator,
scrollLeft: scrollLeft,
scrollRight: scrollRight,
setCSSProperties: setCSSProperties,
Expand Down
6 changes: 3 additions & 3 deletions Sources/Navigator/EPUB/Scripts/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ export function scrollToPosition(position, dir) {

// Scrolls to the first occurrence of the given text snippet.
//
// The expected text argument is a Locator Text object, as defined here:
// The expected text argument is a Locator object, as defined here:
// https://readium.org/architecture/models/locators/
export function scrollToText(text) {
let range = rangeFromLocator({ text });
export function scrollToLocator(locator) {
let range = rangeFromLocator(locator);
if (!range) {
return false;
}
Expand Down

0 comments on commit a3635b5

Please sign in to comment.