Skip to content

Feature/render custom spread pages properties#2

Draft
lbeus wants to merge 17 commits intodevelopfrom
feature/render-custom-sperad-pages-properties
Draft

Feature/render custom spread pages properties#2
lbeus wants to merge 17 commits intodevelopfrom
feature/render-custom-sperad-pages-properties

Conversation

@lbeus
Copy link
Owner

@lbeus lbeus commented Dec 9, 2025

EPUBNavigatorDelegate

Readium allows rendering EPUB spine elements in a custom way (e.g. PDF is rendered using PDFKit instead of being loaded in WKWebView).
Client can provide custom view for given spread using

    func navigator(_ navigator: EPUBNavigatorViewController, viewControllersForReadingOrderLinks links: [Link]) -> (left: UIViewController?, center: UIViewController?, right: UIViewController?)

delegate method.

Returned tuple contains left and right pages if spread has 2 pages. Center property is used in case spread has 1 page.
In case any of spread pages doesn't require custom view nil is returned for such page, and readium will fallback to webview rendering.

links contains array of EPUB spine element links (if spread has 2 pages it will have 2 links, otherwise 1 link).
EPUB document could hold JSON resource which contains mapping of spine element links to metadata model needed to perform custom rendering (e.g. asset hrefs, custom view type info ...)

In order for this method to be invoked for given resource/spine element must have ```properties``` attribute configured with appropriate metadata needed to able to render custom spread.

```html
<item id="item-page-1" href="001-chapter.xhtml" media-type="application/xhtml+xml properties="document:pages/pg-1605839.pdf custom-type:pdf"/>
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can discuss how we could name properties used to describe custom type.

@lbeus lbeus self-assigned this Dec 9, 2025
@lbeus lbeus marked this pull request as draft December 9, 2025 11:27
@lbeus lbeus requested a review from svenmeyers89 December 9, 2025 11:27
@lbeus lbeus changed the title Feature/render custom sperad pages properties Feature/render custom spread pages properties Dec 9, 2025
let spread = spreads[index]

let linksForSpread: [Link] = spread.readingOrderIndices.map { index in
publication.readingOrder[index]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not mistaken, publication.readingOrder is an array, right? If so, you might want to use safe index here.

let isCustom = linksForSpread.contains(where: { $0.properties.renderOptions != nil })

if isCustom, let customView = delegate?.navigator(self, viewForReadingOrderLinks: linksForSpread) {
let customTypeSpreadContainer = CustomTypeSpreadViewWrapper(spread: spread)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you separate all this logic into a new createCustomTypeSpreadContainer function?

}
let isCustom = linksForSpread.contains(where: { $0.properties.renderOptions != nil })

if isCustom, let customView = delegate?.navigator(self, viewForReadingOrderLinks: linksForSpread) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why customView and not customViewController?

])

// handle case when only one page in spread is custom view
if linksForSpread.count == 2 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you are counting on the preconditions defined here: https://github.com/readium/swift-toolkit/blob/develop/Sources/Navigator/EPUB/EPUBSpread.swift#L27

However, did you see this comment: https://github.com/readium/swift-toolkit/blob/develop/Sources/Navigator/EPUB/EPUBSpread.swift#L18

Does this fit into your initial idea? I find this hard to understand without digging deeper into the SDK implementation...


func navigator(_ navigator: EPUBNavigatorViewController, setupUserScripts userContentController: WKUserContentController)

func navigator(_ navigator: EPUBNavigatorViewController, viewForReadingOrderLinks links: [Link]) -> UIViewController?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func navigator(_ navigator: EPUBNavigatorViewController, viewControllerForReadingOrderLinks links: [Link]) -> UIViewController? 👍

private func parseStringProperties(_ properties: [String]) -> [String: Any] {
var contains: [String] = []
var page: Properties.Page?
var renderCustom: [String: Any] = [:]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyValueProperties seems like a more descriptive name.

import UIKit
import WebKit

public extension Properties {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about renaming RenderMetadata to CustomViewMetadata and renderOptions to customViewMetadata?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants