Git Product home page Git Product logo

webpub-viewer's Introduction

webpub-viewer

A viewer application for web publications, based on NYPL’s prototype, which is itself based on Hadrien Gardeur’s proof of concept.

About the Jellybooks-shared branch

This branch is meant to host changes and improvements that Jellybooks can share with the larger community.

Quickstart

Clone this repo, cd the directory, checkout the jellybooks-branch then

npm install

This should run the npm prepublish script as well, transpiling the TS and SASS files into the dist and viewer folders.

You can run automated tests with

npm test

and transpile at any time with

npm run prepublish

Examples

Examples demonstrate how this webpub-viewer can be used:

  1. with static assets i.e. exploded EPUB files on a server;
  2. with assets served by r2-streamer-js (in-memory model);
  3. embedded in exploded EPUB files themselves.

Example EPUBs The Call of the Wild and A Journey to the Centre of the Earth have been kindly offered by Jellybooks.

Static

The examples/static folder contains the webpub-viewer (viewer folder), two example files (TheCallOfTheWild and AJourneyToTheCentreOfTheEarth folders), and a static-server.js script running a local server using Node.js + Express.

This example runs on https so you’ll need to trust the provided webpubViewer.pem self-signed certificate that node and express use to create an https server.

Re-generating a self-signed certificate

From the repository’s root, the following command has been used on MacOS to create the certificate for localhost:

openssl req -newkey rsa:4096 -x509 -nodes -keyout webpubViewer.pem -new -out webpubViewer.pem -subj /CN=localhost -reqexts SAN -extensions SAN -config <(cat /System/Library/OpenSSL/openssl.cnf <(printf '[SAN]\nsubjectAltName=DNS:localhost')) -sha256 -days 3650

The one provided should run until October 24, 2028.

What’s important is that the cert must have CN=localhost and subjectAltName=DNS:localhost for Chrome. Versions > 58 indeed require a subjectAltName with the proper DNS and/or IP entry/entries.

Trusting self-signed certificates

In order to make the self-signed certificate trusted you need to accept it as a valid certificate on your machine. Doing this will replace red warning (“Unsecured”) notices with a green lock, fully replicating a https/SSL website on localhost for testing. This depends on your platform:

You might need to make it an exception in your web browser so that it can be trusted though (Firefox, Safari, etc.).

Usage

  • Update the webpub-viewer files if needed (npm run examples)
  • Launch the webpub-viewer with npm run static
  • Your terminal should display Express server listening on port 3333 – note it’s also listening to errors so will log them in your terminal as well
  • open https://localhost:3333 in the browser
  • To stop the server, type ctrl + c

Both examples are available on the same origin, as cross-origin will be restricted by browsers and throw an error in the viewer.

For the origin to be considered the same, protocol (http/https), host and port must be the same. See web browsers’ same-origin policy.

Streamed

The examples/streamed folder contains the webpub-viewer (readers/reader-JBKS folder), the r2-streamer-js (ES6/ES2015 bundle in server folder) and example files (epubs folder).

In this example, assets are served by the r2-streamer-js (in-memory model). You can open them using 3 iterations of the webpub-viewer: Hadrien Gardeur’s (the original prototype), NYPL’s, and Jellybooks’.

This example runs on http to get around Service Workers issues across all available readers so you don’t need to do anything.

Usage

  • Update the web reader files if needed (npm run examples)
  • Start the server with npm run streamed
  • Open http://localhost:4444 in the browser
  • Pick a publication
  • You can see its manifest (json) and open it in the webpub-viewer of your choice
  • To stop the server, type ctrl + c

Embedded

The examples/embedded folder contains an example file (alice folder), in which the webpub-viewer is embedded, and an embedded-server.js script running a local server using Node.js + Express.

This example runs on https but is using the same certificate as the static example.

Usage

  • Update the webpub-viewer files if needed (npm run examples)
  • Launch the webpub-viewer with npm run embedded
  • Your terminal should display Express server listening on port 1865 – note it’s also listening to errors so will log them in your terminal as well
  • open https://localhost:1865 in the browser
  • To stop the server, type ctrl + c

Testing

Unit testing

By running:

npm test

You’ll launch 200+ automated tests to make sure everything is OK.

Visual Regression Testing

We are also using backstopJS to test for visual regressions. It can indeed help catch issues with user settings and/or features that would be a lot more difficult to catch in unit testing.

It is preferrable you install backstopjs globally as it is a massive download, and is meant as a command that can be used with different projects – note that if installed locally, it will be tied to npm scripts.

npm install -g backstopjs

Since those tests are relying on Pupeteer, so you’ll also need Chrome/Chromium – ideally latest.

Then you’ll have to launch the https server locally with:

npm run static

The first time you run visual regression tests, you’ll need to create reference screenshots with:

npm run visual-test:init

Then

npm run visual-test

This will test different scenarios, with possible interactions from the user e.g. displaying the TOC, changing the font or font-size, picking sepia or night mode…

A browser window/tab will open with the report so that you can take a deeper look.

If you encounter visual inconsistencies backstopJS doesn’t report on your first run, then do:

npm run visual-test:update

This will update the reference screenshots.

You can also use this command when you made a significant cosmetic change or added new features.

Icons

Icons used in the shared version are part of the official Material Design Icons collection (outline version).

Notes

This version sticks to the existing NYPL architecture, with features added in the spirit of its design.

It fixes some bugs and make their dedicated tests more robust. It was primarily meant as a Proof of Concept readers @ Jellybooks could interact with.

Refactorings (architecture, ReadiumCSS, r2-glue-js, etc.) are longer term but have been planned.

webpub-viewer's People

Contributors

aferditamuriqi avatar aslagle avatar jaypanoz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webpub-viewer's Issues

[Discussion] Let's define de project in more details

From discussions I had yesterday with @JayPanoz and @aferditamuriqi, the goals and definition of the project itself are not so clear.

The overall goal is to develop an SDK (i.e. a consistent set of modules with a clear API) conforming with the Readium Architecture, plus a test app, enabling reading on different browsers different types of publications exposed via a Readium Publication Server (ex. "Streamer").

Is it enough? What do we need to add in order to create proper directions and roadmap for the project?

The thread is to allow project stakeholders to express their opinion on the subject and should end with a common detailed definition of the Readium Web project.

ScrollView issues

Just as a heads-up if you’re using the current master – or the jbks-shared branch…

There’s quite a significant amount of issues with the scroll view, that took an awful amount of time to debug because it’s not obvious – and there’s an off-by-one error courtesy of Safari iOS on top of that.

So the list of issues:

  • chapters’ navigation bar (previous/next) not displayed when you reach the bottom of the current chapter;
  • double-scroll happening in Chrome/Firefox i.e. you scroll and there’s an almost unnoticeable pause in your scrolling → that’s the iframe kinda behaving as a parasite, because its explicit height is not what those browsers expect;
  • in addition, progression is not updated correctly in those browsers;
  • finally onscroll event is not debounced (clear/setTimeout), so as resize, it will fire frantically – after debouncing it, I could see a significant performance boost in some browsers actually.

So to put it simply…

Don’t trust document.body when it comes to scroll. I learn the hard way scrolling is a clusterfuck, and document.body is supposed to be quirks mode.

In other words…

document.scrollingElement || document.body

is the way to go.

This scrollingElement will either be document.documentElement (compat mode) or document.body (quirks mode). And that pretty much solve all the issues, including in the iframe.

IFrameNavigator’s start inconsistencies

So I’m currently debugging that but once again, it’s unclear when I’ll be able to commit it, and it also depends on how we’ll be handling the merges between Bokbasen and Jellybooks. So filling the issue to let people know.

There’s quite a nasty inconsistency related to iframe’s loading across browsers. And we’ve been impacted in public beta – sigh.

By default, it doesn’t have a src in the codebase, which means (non-chromium) MSEdge and Firefox are forcing an about:blank as a src when the IFrameNavigator is started.

In other words, what should be:

  1. Load manifest
  2. handle iframe load

is the following in those browsers:

  1. handle iframe load with about:blank
  2. load manifest
  3. handle iframe load with spine item

The only thing that is preventing the reader to fail in MS Edge and Firefox on subsequent uses is that the manifest is requested every time a chapter is loaded.

When I tried to minimise the number of such requests because I saw quite mind-blowing stuff (e.g. 8 requests of the same manifest to the server within a few seconds) i.e. request it on start then use the one in memory, all hell broke lose, and I found myself in a never-ending loop of blank pages – which explained the bug some users had encountered in public beta.

In other words, you’d better protect yourself against about:blank as the currentLocation in the handleIframeLoad method – it’s still unclear to me but apparently, Chrome and Safari are supposed to do the same in the foreseeable future.

[Discussion] Coordinating with involved parties, and possible roadmap

Several parties are involved in “Readium Web”, which grew organically because those parties were willing to have a “Readium Web” in the first place.

Evident Point has been putting some efforts into maintaining a fork @ https://github.com/evidentpoint/webpub-viewer/tree/refactored to contribute features once things are stabilised – thanks, that’s awesome –, and Jellybooks has already shared part of what it could share a few months ago for example (cf. first merge in this repo).

However, there is more to come, and probably it would help all involved parties to know in advance what features/work others may be sharing in the near term. In the best-case scenario, we could even have a roadmap so that parties can pass the torch to one another, and get some easy wins.

I’d really like involved parties to update one another on their current status so that we can build this roadmap.

On behalf of Jellybooks, here is what we still have to contribute back to Readium:

  • may not be that interesting to the community (???) but we kinda automated performance/Progressive Web Apps tests using Google's Lighthouse CLI – at least it helps us see if we have significant regressions on these points during development.
  • we also localisedthe app, albeit in quite an MVP way as I started from scratch – L10n in Web Apps is quite an interesting subject in the sense current/known practices are just plain terrible and there were a lot of shortcomings in everything I've found during research. This means:
    • we refactored templates so that markup can now be decoupled from settings + the navigator – and you can replace that more easily with the framework du jour e.g. React, vue.js, etc.;
    • we decoupled strings from the markup;
    • we refactored the Icon Library and turned it into an "Icon Factory" – so that aria labels, SVG titles, etc. can be localised as well;
    • we added English, German and French locales, and created a "Locale Factory" that automatically pass the correct strings depending on a BCP-47 language tag.
  • there are minor security and error handling improvements here and there – still a WIP actually so more to come.
  • I'm also working on build improvements and this worries me a little bit, more on that in the next paragraph.

Build improvements mean removing the requireJS dependency, using webpack, and refactoring to ease code-splitting and lazy-loading. Now, if I'm not mistaken, Bokbasen and Evident Point already did remove requireJS and switched to webpack. And it worries me a little bit in the sense I'm re-doing that on our side, and there is quite a risk of having the same feature thrice, but diverging in significant ways.

Note I’ll be super aggressive about code-splitting for business reasons in the future.

We’ll also deal with "about this book", a "share panel", fixed-layout, etc.

Finally, add Reader Lifecycle to the list.

Basically, we had to let the cloud reader know in which state is was for various reasons e.g. active, hidden (to save memory), frozen (it can’t do anything significant) and terminated (it can’t do anything). So the reader is effectively listening to browser events triggered by the user, and reacting to those events.

I pretty much had to normalise all (major) browsers there but we were able to make it reliable and it’s quite a bliss to build on top of that right now.


Lifecycle, I can share that shortly since it is one very specific component you don’t even have to use. Other things, it’s up to the community.


I’d be happy to serve as liaison and/or coordinator if needed.

My impression is that we worked on very different things and there’s no huge overlap so there may well be easy wins for the project as a whole. So I’d be happy to do the heavy administrative/organisation lifting if we can transform that into a roadmap with commits/PRs that won’t make life difficult for the next committer/Pull-Requester.

PDF Intergration

Hi, i'm trying to use webpub-viewer in a web-app, is it possible to view pdf ? Thanks

[Discussion] Accessibility: docs, gaps, guidelines

Please allow me to open this issue so that we can have a shared space to discuss accessibility in the “Reading System” context, we’ll at least be able to move it to another repo at some point in time.

Thanks to the Marrakech Treaty and initiatives such as Daisy’s Inclusive Publishing, accessibility has become a hot topic and a strong priority for a lot of people. For instance, several publishers mentioned it as something important when we discussed “cloud readers” with them.

Problem is – at least to me – in a very naïve way: it’s kinda hard to navigate between User Agent Accessibility Guidelines (UAAG) and docs such as WAI-ARIA Authoring Practices, and others (including WCAG because adaptability through settings, etc.).

Consequently it can be tough to know whether what you’re doing is reasonable to do in the first place, if not doing something and letting the browser handle it is the best option you have, and so on and so forth.

A few practical examples…

Let’s take settings, should this be a menu/menubar? In which case you kinda “declare” you are supporting the corresponding keyboard navigation, cf. Authoring Practices or this article. I mean, I couldn’t even pick between menu and menubar in the first place, in the sense user settings are somewhat very reminiscent of an editor menubar.

Then let’s imagine you have an “about this book” display, exposing metadata for the publication. Surely this could be considered a footer with the role of contentinfo? Or am I missing something? And how do you even markup those contents so that they can make sense in the webpage context?

Should you have a heading in the app’s interface? If so, how? Shall the book title you maybe have on top of the iframe be used?

Should “space” navigation be reimplemented in pagination? So instead of scrolling the doc, you progress one page like some Reading Systems already do?

Should “escape” hide the global menu/toolbar?

Should you attempt to reuse some keyboard shortcuts for some features e.g. increasing font-size or zooming fixed-layout? My worry is that once you start doing shortcuts, maybe you can go too far – i.e. same principle as ARIA role in the sense people tend to overuse it once they start using it.

And finally there is some “tension” between the browser and the web app in UAAG. A quick example: settings profiles + export/import. Is the web app claiming responsibility of that given user settings in its UI? But then, what to make of browsers’ settings e.g. font-size, font-family, etc.? and OS settings e.g. dark UI → night mode?

Note that at least part of those may well apply to native too, although in a different form so I’d really like to work with others on all these points if possible, and maybe have a set of guidelines that can be a lot clearer to deal with – I mean, I got some doubts very quickly, in part because ARIA is powerful hence easy to misuse (cf. all the epubcheck issues about dpub roles recently), and having to navigate across multiple docs is making it some kind of labyrinth at first.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.