From b776325382d392acd9d8a83dd2dbd70634af6562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Wed, 16 Sep 2026 15:23:06 +0200 Subject: [PATCH] Expose the reading order rendered by the navigator --- CHANGELOG.md | 1 + .../Navigator/Audiobook/AudioNavigator.swift | 5 +++++ .../EPUB/EPUBNavigatorViewController.swift | 21 +++++++++---------- Sources/Navigator/Navigator.swift | 7 +++++++ .../PDF/PDFNavigatorViewController.swift | 5 +++++ 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a7b117be3..f3ceb3699f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. Take a look * New `EPUBNavigatorViewController.Configuration.preferredResourceVariant` to choose which variant of each resource is rendered among its `alternates`, such as the XHTML page or its bitmap fallback. * Bitmap resources in the reading order are rendered as fixed-layout, even in a reflowable publication. * New `EPUBNavigatorDelegate.navigator(_:contentInsetFor:)` to customize the content insets of a spread according to its `EPUBLayout`, for example to add margins only around the reflowable resources of a mixed-layout publication. It takes precedence over `navigatorContentInset(_:)`. +* New `Navigator.readingOrder` property returning the reading order actually rendered by the navigator, which may differ from `publication.readingOrder` when a custom reading order or a resource variant is used. ### Changed diff --git a/Sources/Navigator/Audiobook/AudioNavigator.swift b/Sources/Navigator/Audiobook/AudioNavigator.swift index 4f2bd3be78..c89857f656 100644 --- a/Sources/Navigator/Audiobook/AudioNavigator.swift +++ b/Sources/Navigator/Audiobook/AudioNavigator.swift @@ -112,6 +112,11 @@ public final class AudioNavigator: Navigator, Configurable, AudioSessionUser, Lo } public let publication: Publication + + public var readingOrder: [Link] { + publication.readingOrder + } + private let initialLocation: Locator? private let config: Configuration private let audioSession: AudioSessionManaging diff --git a/Sources/Navigator/EPUB/EPUBNavigatorViewController.swift b/Sources/Navigator/EPUB/EPUBNavigatorViewController.swift index 237e51ca96..454cfa7301 100644 --- a/Sources/Navigator/EPUB/EPUBNavigatorViewController.swift +++ b/Sources/Navigator/EPUB/EPUBNavigatorViewController.swift @@ -296,9 +296,8 @@ open class EPUBNavigatorViewController: InputObservableViewController, viewModel.config } - /// Reading order rendered by the navigator. - private var readingOrder: EPUBReadingOrder { - viewModel.readingOrder + public var readingOrder: [Link] { + viewModel.readingOrder.links } /// Creates a new instance of `EPUBNavigatorViewController`. @@ -635,7 +634,7 @@ open class EPUBNavigatorViewController: InputObservableViewController, spreads = EPUBSpread.makeSpreads( for: publication, - readingOrder: readingOrder.links, + readingOrder: readingOrder, readingProgression: viewModel.readingProgression, spread: viewModel.spreadEnabled, offsetFirstPage: viewModel.offsetFirstPage @@ -644,7 +643,7 @@ open class EPUBNavigatorViewController: InputObservableViewController, let initialIndex: ReadingOrder.Index = { if let href = locator?.href, - let index = readingOrder.index(of: href), + let index = viewModel.readingOrder.index(of: href), let foundIndex = self.spreads.firstIndexWithReadingOrderIndex(index) { return foundIndex @@ -671,7 +670,7 @@ open class EPUBNavigatorViewController: InputObservableViewController, private func loadedSpreadViewForHREF(_ href: T) -> EPUBSpreadView? { guard let loadedViews = paginationView?.loadedViews, - let index = readingOrder.links.firstIndexWithHREF(href) + let index = readingOrder.firstIndexWithHREF(href) else { return nil } @@ -717,7 +716,7 @@ open class EPUBNavigatorViewController: InputObservableViewController, readingOrderIndices: spreadView.spread.readingOrderIndices, progression: { spreadView.progression(in: $0) }, manifest: publication.manifest, - readingOrder: readingOrder.links, + readingOrder: readingOrder, positionsByReadingOrder: positionsByReadingOrder, tableOfContentsTitleByHref: tableOfContentsTitleByHref ) @@ -759,7 +758,7 @@ open class EPUBNavigatorViewController: InputObservableViewController, public func go(to locator: Locator, options: NavigatorGoOptions) async -> Bool { guard let paginationView = paginationView, - let resolved = readingOrder.resolve(publication.normalizeLocator(locator)), + let resolved = viewModel.readingOrder.resolve(publication.normalizeLocator(locator)), let spreadIndex = spreads.firstIndexWithReadingOrderIndex(resolved.index), on(.jump(resolved.locator)) else { @@ -1053,7 +1052,7 @@ extension EPUBNavigatorViewController: EPUBNavigatorViewModelDelegate { for (_, view) in paginationView.loadedViews { guard let view = view as? EPUBSpreadView, - let index = readingOrder.links.firstIndexWithHREF(href), + let index = readingOrder.firstIndexWithHREF(href), view.spread.contains(index: index) else { continue @@ -1128,7 +1127,7 @@ extension EPUBNavigatorViewController: EPUBSpreadViewDelegate { .joined(separator: "\n") let links = spreadView.spread.readingOrderIndices - .compactMap { readingOrder.links.getOrNil($0) } + .compactMap { readingOrder.getOrNil($0) } for link in links { let href = link.url() @@ -1334,6 +1333,6 @@ extension EPUBNavigatorViewController: PaginationViewDelegate { } func paginationView(_ paginationView: PaginationView, positionCountAtIndex index: Int) -> Int { - spreads[index].positionCount(in: readingOrder.links, positionsByReadingOrder: positionsByReadingOrder) + spreads[index].positionCount(in: readingOrder, positionsByReadingOrder: positionsByReadingOrder) } } diff --git a/Sources/Navigator/Navigator.swift b/Sources/Navigator/Navigator.swift index 863a1f1506..5043a5968b 100644 --- a/Sources/Navigator/Navigator.swift +++ b/Sources/Navigator/Navigator.swift @@ -13,6 +13,13 @@ public protocol Navigator: AnyObject { /// Publication being rendered. var publication: Publication { get } + /// Reading order actually rendered by the navigator. + /// + /// It may differ from `publication.readingOrder` when the navigator was + /// initialized with a custom reading order, or when a resource variant is + /// selected for rendering. + var readingOrder: [Link] { get } + /// Current position in the publication. /// Can be used to save a bookmark to the current position. var currentLocation: Locator? { get } diff --git a/Sources/Navigator/PDF/PDFNavigatorViewController.swift b/Sources/Navigator/PDF/PDFNavigatorViewController.swift index 1002968971..c0151f8a70 100644 --- a/Sources/Navigator/PDF/PDFNavigatorViewController.swift +++ b/Sources/Navigator/PDF/PDFNavigatorViewController.swift @@ -65,6 +65,11 @@ open class PDFNavigatorViewController: private var pdfViewDefaultBackgroundColor: UIColor! public let publication: Publication + + public var readingOrder: [Link] { + publication.readingOrder + } + private let initialLocation: Locator? private let config: Configuration private let editingActions: EditingActionsController