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

navigator.epubReadingSystem injected in EPUB content documents with delay #13

Closed
codingisacopingstrategy opened this issue Nov 30, 2013 · 20 comments
Assignees

Comments

@codingisacopingstrategy

An XHTML spine document with the following body:

<body>
    <script type="text/javascript">
        alert("Hello, my dear friends, my name is" + navigator.epubReadingSystem.name);
    </script>
    <section>FOO BAR</section>
</body>

Will have an alert pop up in the Readium Chrome extension, whereas in the readium-js viewer we get an error:

Uncaught TypeError: Cannot read property 'name' of undefined

screenshot from 2013-11-30 18 47 52

@danielweck
Copy link
Member

Have you tried to query the epubReadingSystem object after body.onload or
document.readystate/dom.loaded? (from the top of my head)
dan

On Saturday, November 30, 2013, Eric Schrijver wrote:

An XHTML spine document with the following body:

<script type="text/javascript"> alert("Hello, my dear friends, my name is" + navigator.epubReadingSystem.name); </script>
FOO BAR

Will have an alert pop up in the Readium Chrome extension, whereas in the
readium-js viewer we get an error:

Uncaught TypeError: Cannot read property 'name' of undefined

[image: screenshot from 2013-11-30 18 47 52]https://f.cloud.github.com/assets/56819/1649171/9e14130a-59e7-11e3-9c1d-00320e80a1ed.png


Reply to this email directly or view it on GitHubhttps://github.com//issues/13
.

@codingisacopingstrategy
Copy link
Author

Hello Daniel,
Thanks for your reaction and suggestion.

I’ve now tried both body onload="function()" and document.addEventListener( "DOMContentLoaded", function, false )

The problem then might be with require.js: because its asynchronous, Readium won’t necessarily be loaded when the book’s JavaScript loads. I’ll try and see if I can get the synchronous version to work.

@codingisacopingstrategy
Copy link
Author

#14

@danielweck
Copy link
Member

The epubReadingSystem object is "injected" into the iframe's window.navigator after the DOM content document is loaded (iframe.onload event). See:

https://github.com/readium/readium-shared-js/blob/develop/js/views/iframe_loader.js

@codingisacopingstrategy
Copy link
Author

Thanks for the pointer.
So how could I make sure epubReadingSystem loaded before I call it?

@danielweck
Copy link
Member

I've used a combination of tricks in my EPUB3 experiments to detect reading
systems (iBooks-iOS, iBooks-MacOSX, Kobo, Readium-Chrome, Readium-JS,
Azardi, GooglePlay, etc.) ... just like browser "sniffing", sigh :(
I have not been playing with ReadiumJS that much, but I think I used
something along the lines of: onDocumentLoaded + setTimeout().
Dan

On Tue, Dec 3, 2013 at 10:57 AM, Eric Schrijver notifications@github.comwrote:

Thanks for the pointer.
So how could I make sure epubReadingSystem loaded before I call it?


Reply to this email directly or view it on GitHubhttps://github.com//issues/13#issuecomment-29700316
.

@bormind
Copy link
Contributor

bormind commented Dec 3, 2013

There is an event ReadiumSDK.Events.READER_INITIALIZED that is fired when reader is initialized.

@danielweck
Copy link
Member

Thanks Boris, this is a useful event to know about from the perspective of an app developer. However, the problem at hand here is that content authors need to be able to access the ePubReadingSystem object from Javascript code contained within XHTML5 spine items, in a platform-agnostic way (i.e. not by hooking into Readium-specific events or objects). The ePubReadingSystem API is useful for content authors who need to determine Reading System capabilities, or simply to detect that a given HTML page is being rendered in the context of a Reading System (rather than within a regular web browser).
Daniel

@bormind
Copy link
Contributor

bormind commented Dec 3, 2013

Daniel, I the context of specific content document the reader fires ReadiumSDK.Events.CONTENT_DOCUMENT_LOADED event and passes out to subscriber the $ifram object and spineItem object.

@danielweck
Copy link
Member

@bormind
Oh yes, sure. However, content authors should never have to hook into the internals of Reading Systems (Readium, iBooks, Kobo, etc.). The purpose of the lightweight ePubReadingSystem API is to expose a common set of platform-agnostic EPUB3 properties (RS capabilities, version, etc.). So hooking into ReadiumSDK.Events would somewhat defy the point.

@bormind
Copy link
Contributor

bormind commented Dec 3, 2013

Daniel, I did some reading on ePubReadingSystem and now I understand it a little bit better. And I think we have a bigger problem - the ePubReadingSystem is relevant not only for browser based but for any reading system. and we should move the ePubReadingSystem object initialization to the shared-js. This will resolve the current issue with initialization too.

@danielweck
Copy link
Member

@bormind it's already in shared-js, but the object gets injected on the iframe.onload event...which is after dom-ready / document loaded, I think.

https://github.com/readium/readium-shared-js/blob/develop/js/views/iframe_loader.js

@bormind
Copy link
Contributor

bormind commented Dec 3, 2013

Yes, I know. But this is wrong. We create ePubReadingSystem in readium.js and store it in navigation object. Then we inject it to the iframe's child window when iframe's content is rendered. This creates reverse dependency and require duplication of ePubReadingSystem creation in other reading systems (Launchers).

@danielweck
Copy link
Member

@bormind in Readium-Chrome, ePubReadingSystem.js used to define the object instance once, this JS file was then boostrapped via reader.html (or other "require" mechanism), then the object got injected into loading iframe. Note that because the ePubReadingSystem object contains an app-specific name + version number, it needs to be updated/intercepted by the application before it gets used inside iframes by content documents (spine items or out-of-spine XHTML).

@codingisacopingstrategy
Copy link
Author

Hello Daniel and Boris,

Thanks for your comments.

content authors need to be able to access the ePubReadingSystem object from Javascript code contained within XHTML5 spine items, in a platform-agnostic way (i.e. not by hooking into Readium-specific events or objects)

Indeed, that would be great! (Though making ePubs feels a bit like the days of the old days of HTML, it would be great if we could get by without reader sniffing).

I’m not sure, by the way, that the epubReadingSystem gets correctly inserted into the iFrame in Readium.js—it appears to be present in the host frame rather than the iFrame:

Readium Chrome:

> navigator.epubReadingSystem
undefined
> document.getElementsByTagName('iframe')[0].contentWindow.navigator.epubReadingSystem
Object {name: "Readium", version: "0.9.1", layoutStyle: "paginated", hasFeature: function}

Readium.js Viewer:

> navigator.epubReadingSystem
Object {name: "Readium.js", version: "0.0.1", layoutStyle: "paginated", hasFeature: function}
> document.getElementsByTagName('iframe')[0].contentWindow.navigator.epubReadingSystem
undefined

But I guess I should switch to the devel branch to really follow what’s going on?

Cheers,

@danielweck
Copy link
Member

develop branch, yes.

@bormind
Copy link
Contributor

bormind commented Dec 9, 2013

Eric, for sure the develop branch is the one to use. Please clone readium-js-viewer recursively to correctly pull all the dependencies (sub-projects). Now, the epubReadingSystem is not yet fixed in develop branch. It will be in the few days. We have a code freeze for develop branch right now. The fix will remove the ePubReadingSystem definition from readium.js - it doesn't belong there. Instead default ePubReadingSystem will be set in readium-shared-js. But reading system should override the defaults with appropriate settings. The right place to do this is in the subscription to ReadiumSDK.Events.READER_INITIALIZED event. Example will be provided in readium-js-viewer.

@danielweck
Copy link
Member

Boris, let's make sure that with this approach the ePubReadingSystem object
is ready in time for when a spine item / XHTML content document's
Javascript actually needs to access it, i.e. usually when the window.onload
/ DOM.ready events are triggered inside the iframe host. Remember, the
ePubReadingSystem
object needs to be explicitely injected into the navigator for
each iframe's internal window, as soon as possible. Is there a better
alternative than iframe.onload?
Daniel

On Monday, December 9, 2013, Boris Schneiderman wrote:

Eric, for sure the develop branch is the one to use. Please clone
readium-js-viewer recursively to correctly pull all the dependencies
(sub-projects). Now, the epubReadingSystem is not yet fixed in develop
branch. It will be in the few days. We have a code freeze for develop
branch right now. The fix will remove the ePubReadingSystem definition from
readium.js - it doesn't belong there. Instead default ePubReadingSystem
will be set in readium-shared-js. But reading system should override the
defaults with appropriate settings. The right place to do this is in the
subscription to ReadiumSDK.Events.READER_INITIALIZED event. Example will be
provided in readium-js-viewer.


Reply to this email directly or view it on GitHubhttps://github.com//issues/13#issuecomment-30151477
.

@bormind
Copy link
Contributor

bormind commented Dec 10, 2013

Daniel, you are absolutely right - I think there is a better way to set ePubReadingSystem than using ifrme's onload. Because READER_INITIALIZED is triggered before iframes are created (they are created on opening spine items). If reading system will use reader's READER_INITIALIZED event to set ePubReadingSystem (or with defaults set in readium-shared-js) we will be able to pass the ePubReadingSystem to iframe's window.navigation. when iframe is just created and not when iframe is loaded with the document.

Boris.

codingisacopingstrategy added a commit to codingisacopingstrategy/osp.workshop.self-conscious-design that referenced this issue Jan 2, 2014
…e }}.

Does not work in the bundled readium-js-viewer. Does work in the Readium
Chrome extension. Bug report: readium/readium-js-viewer#13

Checks for the existence of the navigator.epubReadingSystem property;
so the reader knows if they knows something about themself:
if not, they leave the text alone.
@danielweck danielweck changed the title Not able to call navigator.epubReadingSystem from inline scripts (require.js conflict?) navigator.epubReadingSystem injected in EPUB content documents with delay Jul 7, 2014
@danielweck danielweck self-assigned this Jul 7, 2014
@danielweck
Copy link
Member

Issue moved here:

readium/readium-shared-js#41

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

No branches or pull requests

3 participants