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

How to detect when page is loaded #53

Open
rkwright opened this issue Mar 24, 2015 · 6 comments
Open

How to detect when page is loaded #53

rkwright opened this issue Mar 24, 2015 · 6 comments

Comments

@rkwright
Copy link
Member

From Tom Feldman:
Hi all,
I'm wondering if there is an api somewhere in the readium-shared-js or maybe even some standard javascript I can execute to know when javascript is done figuring out its paging routine. I was previously under the impression that a call to ReadiumSDK.reader.openPageNext() would result in a single callback request of pageDidChange when it was finished. If the spine item changes however, this callback is being requested more than once.

Here's a log of the requests:

2015-03-24 10:44:48.837 SDKLauncher-iOS[2135:209217] Request: file:///private/var/mobile/Containers/Bundle/Application/09A8C37D-532B-43BE-A752-EABE857331CB/SDKLauncher-iOS.app/reader.html
2015-03-24 10:44:49.114 SDKLauncher-iOS[2135:209217] Request: epubobjc:readerDidInitialize
2015-03-24 10:44:49.130 SDKLauncher-iOS[2135:209217] Request: about:blank
2015-03-24 10:44:49.210 SDKLauncher-iOS[2135:209217] Request: epubobjc:settingsDidApply
2015-03-24 10:44:49.233 SDKLauncher-iOS[2135:209217] Request: about:blank
2015-03-24 10:44:49.254 SDKLauncher-iOS[2135:209217] Request: http://127.0.0.1:55661/spi-ad.xhtml
2015-03-24 10:44:49.490 SDKLauncher-iOS[2135:209217] Request: epubobjc:pageDidChange?q={"isRightToLeft":false,"isFixedLayout":false,"spineItemCount":22,"openPages":[{"spineItemPageIndex":0,"spineItemPageCount":1,"idref":"spi_ad","spineItemIndex":1}],"canGoLeft_":false,"canGoRight_":true}
2015-03-24 10:44:54.911 SDKLauncher-iOS[2135:209217] Running open next script
2015-03-24 10:44:54.931 SDKLauncher-iOS[2135:209217] Request: about:blank
2015-03-24 10:44:54.937 SDKLauncher-iOS[2135:209217] Ran open next script
2015-03-24 10:44:54.965 SDKLauncher-iOS[2135:209217] Request: epubobjc:pageDidChange?q={"isRightToLeft":false,"isFixedLayout":false,"spineItemCount":22,"openPages":[{"spineItemPageIndex":0,"spineItemPageCount":1,"idref":"spi_ad","spineItemIndex":1}],"canGoLeft_":false,"canGoRight_":true}
2015-03-24 10:44:55.004 SDKLauncher-iOS[2135:209217] Request: http://127.0.0.1:55661/index.xhtml
2015-03-24 10:44:55.230 SDKLauncher-iOS[2135:209217] Request: epubobjc:pageDidChange?q={"isRightToLeft":false,"isFixedLayout":false,"spineItemCount":22,"openPages":[{"spineItemPageIndex":0,"spineItemPageCount":1,"idref":"id-id2442754","spineItemIndex":2}],"canGoLeft_":true,"canGoRight_":true}

You'll notice one call to the open next script and two pageDidChange events.

@danielweck
Copy link
Member

@nodehack (Tom Feldman), this looks like the first event is a "ghost" of the first one (see the different idref). @jccr (Juan Corona) I seem to remember you mentioning having come across the same issue recently, but maybe I am mistaken?

@nodehack
Copy link

Looks like readium fires a pageDidChange event when setting view settings. The code shows that each time you open a page..if the the view type did not change then we set the view settings. I think this is incorrect. We should only be setting view settings if the desired view type changes.

In reader_view.js :

function openPage(pageRequest, dir) {

        initViewForItem(pageRequest.spineItem, function(isViewChanged){

            if(!isViewChanged) {
                _currentView.setViewSettings(_viewerSettings);
            }

            _currentView.openPage(pageRequest, dir);
        });
    }

I think you only want to setViewSettings if the desired view type changed..so it should read:

function openPage(pageRequest, dir) {

        initViewForItem(pageRequest.spineItem, function(isViewChanged){

            if(isViewChanged) {
                _currentView.setViewSettings(_viewerSettings);
            }

            _currentView.openPage(pageRequest, dir);
        });
    }

Thoughts?

Edit:
Actually..upon further investigation I'm not sure why we need that if statement. initViewForItem already calls setViewSettings if the view type did change.

@jdempcy
Copy link

jdempcy commented Mar 24, 2015

I had to code around this issue. Here is my workaround, which I do not advise as a permanent solution, but may be of assistance.

My goal was to register an onclick event on particular elements like audio and video tags. I need to register the event handler any time the DOM is overwritten and I assume it has to be triggered by a PAGINATION_CHANGED ("pageDidChange") event.

I was getting the problem where hooking into this event resulted in multiple registrations of my event handlers, so a single click would fire a function multiple times.

My solution was to set a flag on the HTML root node itself, knowing that I only need to re-register the event handlers when the HTML node was destroyed. You can see my code here:

// Register event handlers inside the iframe when it is loaded
ReadiumSDK.on(ReadiumSDK.Events.READER_INITIALIZED, function () {
  ReadiumSDK.reader.on(ReadiumSDK.Events.PAGINATION_CHANGED, function () {
    var $iframe = $('iframe');
    var $htmlElement = $iframe.contents().find('html');
    if ($htmlElement.attr('isEventHandlingRegistered')) {
      // Do nothing
    } else {
      $htmlElement.attr('isEventHandlingRegistered', 'true');
      $iframe.contents().find('audio, video')
          .on('click', function (e) {
            // Event handler code
          });
    }
  }); // End PAGINATION_CHANGED
}); // End READER_INITIALIZED

If I could rely on PAGINATION_CHANGED to only be triggered when the DOM is overwritten, I could remove the code which checks for a flag. But the solution outlined above seems to be working okay for me for now, so it isn't a blocking issue for me.

@danielweck
Copy link
Member

FYI, I filed an issue here about the duplicated event: readium/readium-shared-js#172

@jdempcy note that PAGINATION_CHANGED is triggered every time a reflowable document's page layout is potentially (but strictly-speaking: not necessarily) altered, for example due to changes in font size, line spacing, margins, viewport resizing, etc.
The CONTENT_DOCUMENT_LOADED event is probably the one to use, if you need to inject behaviours only once per HTML DOM.

@nodehack
Copy link

nodehack commented Apr 1, 2015

@danielweck I added ReadiumSDK.reader.on(ReadiumSDK.Events.CONTENT_DOCUMENT_LOADED, this.onDocumentLoaded, this); to host_app_feedback.js and it does fire however I don't get any feedback to the native side via the request.

My onDocumentLoaded looks like:

    this.onDocumentLoaded = function() {
        window.location.href = "epubobjc:documentLoaded";
    };

Am I missing a step somewhere?

@danielweck
Copy link
Member

@nodehack to wire the event into a native behaviour, add some handling code here:
https://github.com/readium/SDKLauncher-iOS/blob/master/Classes/EPubViewController.m#L593

NSString *s = @"epubobjc:";

    if ([url hasPrefix:s]) {
        url = [url substringFromIndex:s.length];

        if ([url isEqualToString:@"documentLoaded"]) {

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

No branches or pull requests

4 participants