Last active
November 21, 2017 19:39
-
-
Save jccr/a61a59d1839f508f55d18e767c1e7f17 to your computer and use it in GitHub Desktop.
Readium location linking for a Readium reader embedded in an iframe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Needs URLSearchParams polyfilled for IE | |
// The most referenced one is this: | |
// https://github.com/WebReflection/url-search-params | |
(function () { | |
// Selector for the iframe element embedding Readium | |
var readiumIframe = document.querySelector('iframe'); | |
// It's a good idea to focus on the Readium frame. | |
// This bring it in keyboard focus right away. | |
readiumIframe.focus(); | |
// Used to hook into the iframe hosting Readium | |
// after it 'unloads' its initial empty document | |
// and begins to load the actual document. | |
readiumIframe.contentWindow.addEventListener('unload', function () { | |
setTimeout(function () { | |
bindToIframe(readiumIframe); | |
}, 0); | |
}); | |
function bindToIframe(iframe) { | |
// Bring the appropriate search (query) params and fragment | |
// from the top window URL to the iframe window URL | |
setIframeWindowSearchParams(window, iframe.contentWindow); | |
getReadium(iframe.contentWindow, function (ReadiumSDK, reader) { | |
reader.on(ReadiumSDK.Events.PAGINATION_CHANGED, function () { | |
// Execute after all pagination changed event handlers | |
setTimeout(function () { | |
// Bring the appropriate search (query) params and fragment | |
// from the iframe window URL to the top window URL | |
setTopWindowSearchParams(window, iframe.contentWindow); | |
}, 0); | |
}); | |
}); | |
} | |
function getReadium(iframeWindow, callback) { | |
var readiumSdkVar; | |
// Intercept the global ReadiumSDK object assignment using a property. | |
// This works because this will run before the Readium script is executed. | |
Object.defineProperty(iframeWindow, 'ReadiumSDK', { | |
get: function () { | |
return readiumSdkVar; | |
}, | |
set: function (ReadiumSDK) { | |
if (!readiumSdkVar) { | |
ReadiumSDK.once(ReadiumSDK.Events.READER_INITIALIZED, function (reader) { | |
callback(ReadiumSDK, reader); | |
}); | |
} | |
readiumSdkVar = ReadiumSDK; | |
} | |
}); | |
} | |
function getWindowLocation(targetWindow) { | |
// Obfuscate the location lookup a bit so the part of the hypothesis' via proxy | |
// that's rewriting this script doesn't mangle window.location references like this | |
return targetWindow['location']; | |
} | |
function setIframeWindowSearchParams(topWindow, iframeWindow) { | |
var iframeWindowLocation = getWindowLocation(iframeWindow); | |
iframeWindowLocation.hash = topWindow.location.hash; | |
var iframeUrlSearchParams = new URLSearchParams(iframeWindowLocation.search); | |
var topWindowSearchParams = new URLSearchParams(topWindow.location.search); | |
if (topWindowSearchParams.has('goto')) { | |
iframeUrlSearchParams.set('goto', topWindowSearchParams.get('goto')); | |
} | |
var newUrl = iframeWindowLocation.pathname + '?' + iframeUrlSearchParams.toString() + topWindow.location.hash; | |
iframeWindow.history.replaceState({}, '', newUrl); | |
} | |
function setTopWindowSearchParams(topWindow, iframeWindow) { | |
var iframeWindowLocation = getWindowLocation(iframeWindow); | |
var iframeUrlSearchParams = new URLSearchParams(iframeWindowLocation.search); | |
if (iframeUrlSearchParams.has('goto')) { | |
var topWindowSearchParams = new URLSearchParams(topWindow.location.search); | |
topWindowSearchParams.delete('goto'); | |
var topWindowSearchParamsString = topWindowSearchParams.toString(); | |
if (topWindowSearchParamsString.length) { | |
topWindowSearchParamsString = topWindowSearchParamsString + '&'; | |
} | |
topWindowSearchParamsString = topWindowSearchParamsString + 'goto=' + encodeURI(iframeUrlSearchParams.get('goto')); | |
var newUrl = topWindow.location.pathname + '?' + topWindowSearchParamsString; | |
topWindow.history.replaceState({}, '', newUrl); | |
} | |
} | |
function disableHypothesisSidebar(targetWindow) { | |
// The top level Hypothesis sidebar needs to be disabled | |
// so the one inside the Readium frame is used instead | |
//TODO | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment