readium / readium-js-viewer

👁 ReadiumJS viewer: default web app for Readium.js library
BSD 3-Clause "New" or "Revised" License
550 stars 186 forks source link

External Links in InDesign don't work #350

Open rkwright opened 9 years ago

rkwright commented 9 years ago

A document created in InDesign has external links. They "work" in iBooks (though the target is 404) but not in the Chrome Extension. The user posted the file for me (1.45 GB!) which I downloaded. Loaded it into ID and removed all but 2 pages. Still demonstrated the problem (works in iBooks, not in RCE nor in SDKLauncher-OSX).

Here's the HTML: Taking the EPUB apart a bit I see that here is the calling HTML

    <div id="_idContainer039" class="_idGenButton" data-releaseactions="goToDestination(&apos;http://we.mmm.com/wiki/display/HCB/Compass+Growth+Programs+and+Tools+Phase+2&apos;);">
        <div class="_idGen-Appearance-Normal" id="_idContainer038">
            <div id="_idContainer036" class="_idGenObjectStyle-Disabled">
                <img class="_idGenObjectAttribute-1 _idGenObjectAttribute-2" src="image/32.png" alt="" />
            </div>
            <div id="_idContainer037" class="_idGenObjectStyle-Disabled">
                <img class="_idGenObjectAttribute-1 _idGenObjectAttribute-2" src="image/33.png" alt="" />
            </div>
        </div>
    </div>

And here is the JS that handles the MouseUp, finds the data-release actions and invokes the browser to go eval the link:

function onMouseUp(element, event) {
var is_touch_device = 'ontouchstart' in document.documentElement;
if (is_touch_device) return;
removeClass(element, '_idGenStateClick');
var actions = element.getAttribute("data-releaseactions");
if(actions) {
eval(actions);
}

And here is the console output: err So it may be that we are doing the right thing? However, this is export from ID, so either way this is a problem.

rkwright commented 9 years ago

The document is highly proprietary so contact me if you want a copy to test.

ryanackley commented 9 years ago

Can you find and paste the contents of the goToDestination function? This is what is trying to open the link.

rkwright commented 9 years ago

Ah, thought I had. Here it is:

 function goToDestination(ref) {
 window.location.href = ref;
 }
rkwright commented 9 years ago

Further comment from the user: "What I found to work was: Originally I created url link's as buttons in Indesign's Interactive Panel - Buttons and forms. I created each as a button and assigned it an action: “Go to URL”. And that worked before update. The way I fixed it was I went to the linked item on page…. right clicked it and selected “Interactive" and selected “convert to object” causing it to no longer be a button or anything. Then I select my item again and went to “interactive panel” And instead of button choose hyperlink and placed my url there and I have had no problems since."

ryanackley commented 9 years ago

Unfortunately, I don't see an easy way to fix this. We would have to inject a script into every single book on the possibility it might be authored by ID.

So the script is basically saying "open this external url inside the epub viewer." Seems like bad practice to me.

rkwright commented 9 years ago

What would such a script do? Note that this approach works in iBooks. Any speculation on how they manage it?

ryanackley commented 9 years ago

iBooks is a native application that can make its own rules. We're restricted by the Chrome app security model. That security model prevents us from opening external content inside an iframe.

There is a special tag for embedding web content in apps but we lose the ability to talk directly to the iframe which is required by readium.

We could inject a script that overrides goToDestination to call window.open instead. This would open the url in a separate tab or window instead of trying to navigate the epub viewer to an external url.

rkwright commented 9 years ago

Ah, OK. Makes sense. I think that is way over the top, especially as the user found a workaround. It is also another item to be documented...

danielweck commented 9 years ago

I have been using this HTML snippet to test various flavours of hyperlinks:

<p>
<a href="http://readium.org">http://readium.org</a>
</p>
<p>
<a href="http://readium.org" target="_BLANK">same link with @target=_BLANK</a>
</p>
<p>
<button onclick="Javascript:window.location.href='http://readium.org';">location.href=xxx</button>
</p>
<p>
<button onclick="Javascript:window.open('http://readium.org');">window.open(xxx)</button>
</p>

As Ryan said, window.open() works fine.

danielweck commented 6 years ago

Note that this is solved in Readium2 Electron-TypeScript navigator thanks to low-level handling of webview navigation events via the Electron API. Other R2 platforms (e.g. Android-Kotlin, iOS-Swift) probably have to handle this differently.