Skip to content

Instantly share code, notes, and snippets.

@jccr
Last active November 21, 2017 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jccr/a61a59d1839f508f55d18e767c1e7f17 to your computer and use it in GitHub Desktop.
Save jccr/a61a59d1839f508f55d18e767c1e7f17 to your computer and use it in GitHub Desktop.
Readium location linking for a Readium reader embedded in an iframe
// 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