Closed rkwright closed 7 years ago
From Jean-Marie: Probably per-platform. On iOS it would be great to get some insurance from Apple that the paginationMode that has become private in WkWebview (but can be used) will not disappear… Is this realistic?
On Android the situation is more complex ;-)
From Jean-Marie:
Here is the code snippet that does the trick:
<body style="overflow:-webkit-paged-x; overflow:paged-x;">
It flies!!! Tested on huge pages on Android devices. Instant display, blazing-fast horizontal scroll.
It was implemented in 2012, I didn't know that. https://trac.webkit.org/changeset/126343
From Juan Corona: I'm for the the per-platform approach. But one of my concerns is with the increased overhead supporting multiple strategies for serializing/deserializing page locations, figuring out visible page ranges, and all the related code we wrote in the cfi_navigation_logic monolith. Although if we can keep things modular and with well designed interfaces I can see this burden being eased.
From Jean-Marie:
seems to work like a charm (very fast) on Android Chromium (available since 4.4 and even before for those who embed a Chromium-based WebView) and on iOS too. Any known drawback? My first tests cumulating this pagination and multi columns (are not very positive (it works but thare are small scrolling issues on iOS and viewport issues on Android), but we can dig [into them] if nobody already has negative conclusions. Edit: I see that this option was discussed back in 2014...From Juan Corona: I wasn't part of the discussion back in 2014, but if this is a viable strategy for Android then it sounds great.
From Juan Corona: CSS scroll snap points provide a nice scrolling experience, as if flipping through pages. https://www.chromestatus.com/feature/5721832506261504 It’s supported everywhere but Chrome and IE (but is shipped in Edge!) Demo (vertical, but can be horizontal): https://blog.hospodarets.com/demos/scroll-snap-full-screen
Using overflow-paged sounds very promising. However, to be viable it needs to work on all platforms we support (if at all possible). It is much more complex to have one solution for MOST platforms and one or two others on other platforms. We need some research into how works across different platforms and versions. Also, is this a feature that the browser vendors will continue to support or will they drop it just as we finish R2?
I've made little demos using overflow: -webkit-paged-x
with scroll snapping. It's a lovely experience, requiring three lines of CSS:
overflow: -webkit-paged-x;
-webkit-scroll-snap-type: mandatory;
-webkit-scroll-snap-points-x: repeat(100%);
But AFAIK it's only working publicly in Desktop Safari. Sadly, I haven't heard of interest from other browsers for this.
@dauwhe Can you share your demos?
Right. Theoretically it should work on all webkit-based webviews... It seems to be present at least since 2012 in WebKit (See this description). We should probably define a fallback strategy however, for browsers that don't support it or don't support it well... PS: - Just for fun - While doing some random "googling" on this topic I found a funny paper to read later... They transform the page with XSLT to break the page into pages, so preserving the CFIs with this technique is probably a little bit tricky ;-) But this is probably an entry point to the world of of pagination, and the References section contains some interesting stuff (...for insomniacs ;-))
@dauwhe Thanks. I see the pagination layout but how is the snap-navigation supposed to work?Seems to simply lay out the "pages" then you have to manually move the viewport so a given page is in view. Tested in Safari 10.0 on OSX.
@dauwhe According to my tests, the paged-x works fine on my Android Webkit-based webviews and on iOS. Snap points don't.
@rkwright if I do the horizontal two-finger gesture on my trackpad, the "page" slides and then sticks to the snap point. It's very much like page-swipe gestures in many EPUB reading systems.
One bad thing is that, at least in my file, when I go to a page via a TOC link, it doesn't automatically snap to the page boundary. I have to nudge it.
Works fine for me on macOS with Safari, no snap points with Chrome though.
@dauwhe Ah so. Yes, that works. But clearly there are a bunch of wrinkles to this approach. But if it can be made to work it would be a great boon. And after all, WebKit is open source.
Shock! It doesn't work in Edge. And last time I looked, Edge wasn't open source...
Interesting reference about Edge
@jmgeffroy Huh. I hadn't stumbled on that. But I don't see the source code. Still, interesting.
@rkwright The source code isn't there but it contains interesting stuff and pointers. It's on this Github repo that I found the link to the Edge Platform Status page, for example. It's also probably interesting to look at the tests. It's reading the Webkit tests that I discovered the overflow: paged-x, for example. At least, it's easier to read than the complete source code in a first approach...
At the W3C TPAC, CSS Houdini was cited as a possible great solution for our pagination problem. It would be a DIY solution, where we create a pagination CSS polyfill in JS (more that a polyfill, a real new thing).
More specifically, I was advised by A.Stearns (Adobe), co-chair of the CSSWG, that:
readium architecture folks should consult https://drafts.css-houdini.org/css-typed-om/ and http://wicg.github.io/CSS-Parser-API/ and give feedback on whether they would be useful to you.
The new liaison between the publishing industry and the W3C could help us getting more from the browser vendors.
Of course, there is also: http://sorotokin.com/adaptive-layout/ The CSS working group reviewed it several years ago. Some liked it, some didn't. But it is very nice, very full-featured and works.
@rkwright Vivliostyle has used Peter's work as the basis for their stuff. https://github.com/vivliostyle
Note that I met Florian Rivoal from Vivliostyle at TPAC, we talked about their work, achieved from sorotokin's work. They have some open-source software they could share.
FYI the CSS paged-x property doesn't seem to work in Safari on iOS (version 10).
You should always include both paged-x and -webkit-paged-x in your test.
Well support looks buggy: I was indeed able on iOS to "page" some content by adding the CSS to a simple HTML page, but @dauwhe's example displays a very long iframe on my iPad:
I've also created a demo for paged-x: https://hadriengardeur.github.io/webpub-manifest/examples/pagination/overflow-paged-x/
Just a few notes about the demo:
My main concern regarding -webkit-paged-x is that I can't find a single way to set a top and bottom margin on overflowed content (page 2+).
Top and bottom margin can easily be outside the overflowed area. 3 obvious "pros" of this solution wrt multi-column are simplicity, speed and the fact that it doesn't break multi-columned layouts. Note that I'm still studying other solutions, so I'm not pushing it as the only way to go. Peter Sorotokin's adaptive layout is impressive (as always) but I don't know how fast it can be. BTW more generally I think that pagination strategy is probably one of the areas that should be normalized as much as possible across all implementations and integrations if we still want to fulfill the promise of "providing a unified Epub 3 rendering"...
@jmgeffroy that means introducing a synthetic margin (top/bottom) that won't respect the publication's CSS. Sure that works, but it's slightly inconsistent with the author's intent.
BTW more generally I think that pagination strategy is probably one of the areas that should be normalized as much as possible across all implementations and integrations if we still want to fulfill the promise of "providing a unified Epub 3 rendering"...
Do you mean normalized across apps on the same platform or normalized across different platforms?
Peter's adaptive layout was (is) very performant. The more serious problem was that it had to essentially take over CSS layout from the browser. Even so it was performant (Peter at his best) but IIRC it did interfere with accessibility (or at least was never optimized to support accessibility properly).
My larger concern in this area (and with paged-x in particular) is having a consistent solution across the supported platforms.
I've created a more advanced demo (limited to desktop Chrome/Safari/Opera and Chrome on Android for now) that does the following:
It's entirely based on "overflow: paged-x" with very little JS/CSS injected in the iframe.
It's available at https://hadriengardeur.github.io/webpub-manifest/examples/paged-viewer
Just a quick update based on something that @rkwright said yesterday and that @olivierkorner mentioned earlier in this thread:
Overall, this means that while "overflow: paged-x" works really quite well on Webkit-based browsers on either desktop (Chrome, Opera, Safari) or on Android (Chrome), it's not supported at all in Edge/Firefox and doesn't behave properly in an iframe on iOS.
In order to continue these tests with various techniques for pagination, I'd like to set up a test environment that would have the following components:
I've also listed the following things that IMO have an impact on pagination and aren't mentioned as often in our discussions:
There are also a number of pagination solutions for which we can't do the implementation strictly in JS: using multiple webviews, private APIs on WKWebview etc. Should we also test some of these solutions? Do we have a good idea how various RS actually implement pagination (iBooks, Kindle, Kobo, Google, Scribd...)?
I'm just starting to play with the idea of not using iframes at all. They cause issues with paged-x
(at least on mobile), they can get in the way when using VoiceOver or TalkBack (as the browser sees the iframe as another container to be navigated into), et cetera.
The whole point of using an iframe, at least as far as I know, is to be able to maintain an outer container for the reading system with the iframe being responsible for holding the contents of the book. This certainly makes sense if the goal is to be able to move between different chapters of a book all within the browser as is presently the case with Readium.
At least on mobile though, I think another solution is possible. We could get rid of the iframe, make the browser responsible only for showing a single chapter, and then load up other chapters in different web views that are then swapped into view as appropriate by the application-layer code written in Java, Swift, et cetera. This approach would seem to eliminate the need for an iframe, would make precaching adjacent spine items very simple, and would allow more work to be lifted out of the land of JavaScript and brought into the application layer.
It may well be possible to use the same approach on the desktop as well. Electron has a web view component that presumably could be used to the same effect as WKWebKit
and android.webkit.WebView
. I need to look into this a bit further.
@winniequinn This is not a bad idea (at all). Iframes are certainly not ideal. However, trying to put separate spine items in separate containers has been tried more than once. See the prefetch branch in shared-js. One of the major problems encountered is NOT playing audio and video (as well as scripting) before the web-view is "brought into view". Both EvidentPoint and Bluefire experimented with it, but were unable to resolve it satisfactorily. But YMMV... It WOULD be a good approach if the problems can be resolved.
This feels like two separate discussions:
I'm also in favour of either dropping the iframe or offering an alternative, as I've said before in https://github.com/readium/readium-2/issues/12#issuecomment-255015051
How we actually handle different spine items is another question, probably worth having its own issue here.
@winniequinn this is how other "i"-named reading systems do it.
In Readium-1 we have reader.html
that effectively bootstraps the entire readium-shared-js
subsystem (rendering engine), which lays out the EPUB content iframe
hosts, and is responsible for injecting behaviours into spine items (Media Overlays, link hijacking, keyboard / input device intercept and forwarding, CSS styling, epubReadingSystem, MathJax, etc.).
Using native webviews instead of iframes would mean writing a large portion of the rendering code in native per-platform code, which I think is acceptable in the context of Readium-2.
Note that we did look into using Electron's special web frame, but this is basically an extended iframe with special features (still in the renderer process though).
Continued iframe
discussion:
https://github.com/readium/readium-2/issues/15
During our weekly-call, @JCCR volunteered to create a prototype based on CSS-columns in order to continue to explore and compare various options for pagination.
Added the example for CSS-columns on develop: https://github.com/readium/readium-2/tree/develop/examples/pagination/columns
I see that @HadrienGardeur did the same for overflow: paged-x
:
https://github.com/readium/readium-2/tree/develop/examples/pagination/overflow-paged-x
Thanks @JCCR that's very helpful.
I'll try to adapt my WebPub Viewer code as soon as possible to provide the ability to quickly switch between pagination modes. I'd like to roll out a full test suite where we can test a number of EPUB live and switch between different pagination modes.
Note I filed a bug on the webkit iframe issue: https://bugs.webkit.org/show_bug.cgi?id=165304
@dauwhe thanks Dave !
In other news, I'd like to discuss the APIs available for the pagination module in the next call. No matter what we decide to use in order to paginate, we could have a number of APIs that work across all implementations (even for native code).
Let's start with some basic stuff that we can all agree on and expand from there.
@HadrienGardeur started that page: https://github.com/readium/readium-2/tree/master/doc/pagination
The location of the document seems to have changed. This works for me: https://github.com/readium/readium-2/tree/master/pagination
For the (track) record, explored overflow: paged-x
as soon as we started working on pagination for Readium CSS and it was quite unreliable. For some reason, blink’s and webkit’s implementations differ a lot, with Blink being more complete.
There are simply too many issues at the moment:
background-color
doesn’t work in Safari if the element has overflow: paged-x
declared, which is problematic for reading modes, while it works in Chrome; scrollWidth
while Chromes does. So only chrome sets the scrollWidth
of the element as a multiple of the viewport width;left: value
to make it scroll everywhere, scrollLeft
didn’t work with columns for some reason. It is also my understanding that Opera’s intent was to use it to solve a lot of the column-box model issues and limitations (padding
, margin
, overflow
, position: fixed|absolute
etc.). I’m taking the Presto’s implementation (Opera Reader) as a reference there since it was feature complete.
So they used it with columns anyway, it was not designed as a replacement but more like a sanitizer for paged media.
By the way @JayPanoz which page should we reference officially for the pagination strategy in Readium CSS?
@HadrienGardeur Well, stylesheets are currently in branches (mapped to the project’s phases) as I can’t necessarily PR parts of the CSS as they come along e.g. pagination impacts user settings and vice versa. Besides, we still have to deal with scroll at the moment, which once again is impacting/impacted by user settings.
In other words, I’ll be able to PR when we have a fundamental system designed and then improve details.
But I can edit the Readium CSS wiki for reference in the meantime, especially as we now know how we’ll inject contents. That was on my TODO list and I’ll have to wait for basic user settings to be implemented in the iOS proto anyway so I can prioritize that tomorrow.
BTW, which would be the best repo to discuss the iOS proto issue about odd number of columns when two-column view? I may have an idea, which could also save us a lot of layout trashing, but Daniel could probably give a lot of insights about it as it would impact CFI at first sight.
This is a Discussion