Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new experimental EPUB FXL navigator #567

Open
wants to merge 62 commits into
base: develop
Choose a base branch
from
Open

Add a new experimental EPUB FXL navigator #567

wants to merge 62 commits into from

Conversation

qnga
Copy link
Contributor

@qnga qnga commented Sep 17, 2024

No description provided.

@@ -74,3 +78,4 @@ project(":readium:streamer")
.name = "readium-streamer"

include("test-app")
include(":readium:navigators:demo")
Copy link
Member

Choose a reason for hiding this comment

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

Can we keep this commented out for now, to avoid confusing integrators with two test apps?

@@ -0,0 +1,2 @@
!function(){"use strict";class t{constructor(t,i){if(this.margins={top:0,right:0,bottom:0,left:0},!t.contentWindow)throw Error("Iframe argument must have been attached to DOM.");this.listener=i,this.iframe=t,this.iframe.addEventListener("load",(()=>{this.onIframeLoaded()}))}show(){this.iframe.style.display="unset"}hide(){this.iframe.style.display="none"}setMargins(t){this.margins!=t&&(this.iframe.style.marginTop=this.margins.top+"px",this.iframe.style.marginLeft=this.margins.left+"px",this.iframe.style.marginBottom=this.margins.bottom+"px",this.iframe.style.marginRight=this.margins.right+"px")}loadPage(t){this.iframe.src=t}setPlaceholder(t){this.iframe.style.width=t.width+"px",this.iframe.style.height=t.height+"px",this.size=t}onIframeLoaded(){const t=this.iframe.contentWindow.document.querySelector("meta[name=viewport]");if(!t||t instanceof HTMLMetaElement)return;const i=this.parsePageSize(t);i&&(this.iframe.style.width=i.width+"px",this.iframe.style.height=i.height+"px",this.size=i,this.listener.onIframeLoaded())}parsePageSize(t){const i=/(\w+) *= *([^\s,]+)/g,e=new Map;let s;for(;s=i.exec(t.content);)null!=s&&e.set(s[1],s[2]);const h=parseFloat(e.get("width")),a=parseFloat(e.get("height"));return h&&a?{width:h,height:a}:void 0}}class i{setInitialScale(t){return this.initialScale=t,this}setMinimumScale(t){return this.minimumScale=t,this}setWidth(t){return this.width=t,this}setHeight(t){return this.height=t,this}build(){const t=[];return this.initialScale&&t.push("initial-scale="+this.initialScale),this.minimumScale&&t.push("minimum-scale="+this.minimumScale),this.width&&t.push("width="+this.width),this.height&&t.push("height="+this.height),t.join(", ")}}class e{constructor(i,e,s){this.fit="contain",this.insets={top:0,right:0,bottom:0,left:0};const h={onIframeLoaded:()=>{this.layout()}};this.leftPage=new t(i,h),this.rightPage=new t(e,h),this.metaViewport=s}loadSpread(t){this.leftPage.hide(),this.rightPage.hide(),this.spread=t,t.left&&this.leftPage.loadPage(t.left),t.right&&this.rightPage.loadPage(t.right)}setViewport(t,i){this.viewport==t&&this.insets==i||(this.viewport=t,this.insets=i,this.layout())}setFit(t){this.fit!=t&&(this.fit=t,this.layout())}layout(){if(!this.viewport||!this.leftPage.size&&this.spread.left||!this.rightPage.size&&this.spread.right)return;const t={top:this.insets.top,right:0,bottom:this.insets.bottom,left:this.insets.left};this.leftPage.setMargins(t);const e={top:this.insets.top,right:this.insets.right,bottom:this.insets.bottom,left:0};this.rightPage.setMargins(e),this.spread.right?this.spread.left||this.leftPage.setPlaceholder(this.rightPage.size):this.rightPage.setPlaceholder(this.leftPage.size);const s=this.leftPage.size.width+this.rightPage.size.width,h=Math.max(this.leftPage.size.height,this.rightPage.size.height),a={width:s,height:h},r=function(t,i,e){switch(t){case"contain":return function(t,i){const e=i.width/t.width,s=i.height/t.height;return Math.min(e,s)}(i,e);case"width":return function(t,i){return i.width/t.width}(i,e);case"height":return function(t,i){return i.height/t.height}(i,e)}}(this.fit,a,this.viewport);this.metaViewport.content=(new i).setInitialScale(r).setMinimumScale(r).setWidth(s).setHeight(h).build(),this.leftPage.show(),this.rightPage.show()}}var s;!function(t){const i=document.getElementById("page-left"),s=document.getElementById("page-right"),h=document.querySelector("meta[name=viewport]"),a=new e(i,s,h);t.loadSpread=function(t){a.loadSpread(t)},t.setViewport=function(t,i,e,s,h,r){const n={width:t,height:i},o={top:e,left:s,bottom:h,right:r};a.setViewport(n,o)},t.setFit=function(t){if("contain"!=t&&"width"!=t&&"height"!=t)throw Error(`Invalid fit value: ${t}`);a.setFit(t)}}(s||(s={})),Window.prototype.layout=s}();
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't all the stuff in dist be ignored in Git?
But we need their copy in assets to not require integrator to build the scripts themselves.

There's also a step you can add in .github/workflows/checks.yml to verify that the scripts are up to date (see "Check if bundled scripts are up-to-date" in the YAML)

@@ -0,0 +1,317 @@
/*
Copy link
Member

Choose a reason for hiding this comment

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

It could be helpful to gather all the files copied from Android or Jetpack Compose in their own package to identify them. This way if some of them are updated or become public, we can transition more easily.

Did you make any changes to these copied files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most of the files are mine, and some are copies of parts of Compose source files. In which case, I left the AOSP license header.

public data class PrepaginatedWebNavigatorPreferences(
val fit: Fit? = null,
val readingProgression: ReadingProgression? = null,
val spreads: Boolean? = null
Copy link
Member

Choose a reason for hiding this comment

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

We used singular so far in other navigators.

Suggested change
val spreads: Boolean? = null
val spread: Boolean? = null

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly only because the property is not a boolean.

if (pending == null) {
pending = page
} else {
add(DoubleSpread(pending, page))
Copy link
Member

Choose a reason for hiding this comment

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

Why are you using DoubleSpread here and DoubleViewportSpread in the case of RIGHT, and what's the difference between the two?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have a look at the definitions. DoubleSpread is a true double spread with two true pages, DoubleViewportSpread might be a single left or right page. It's a convenience construction shortcut.

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