-
-
Notifications
You must be signed in to change notification settings - Fork 35
Description
Recently I came across an issue: when replaying heavier websites, after clicking on a hyperlink on the page, the frame and banner around the iframe would take a while to update. This happens because wombat notifies the frame about new pages being loaded by posting a message when the 'load' event triggers. However, this event is only triggered after the page completes loading.
My suggestion would be to have wombat post a message on the 'unload' event, which is sent as soon as a change of context is requested. This has the issue that the event happens before the new URL is set on window.location.href
, but by taking heavy inspiration from this StackOverflow answer, I was able to implement the desired behavior.
I implemented it in the pywb custom frame rather than editing wombat.js. When the unload event happens, a message is posted with wb_type
set to 'unload'
, which as far as I could tell is currently an unused wb_type
in wombat.
With this I was able to have the frame react as soon as a hyperlink was clicked. Here is the code I used:
var cframe = new ContentFrame({
"url": "{{ url }}" + window.location.hash,
"prefix": "{{ wb_prefix }}",
"request_ts": "{{ wb_url.timestamp }}",
"iframe": "#replay_iframe"
});
// adding an 'unload' event message to be able to quickly react to changes in context.
const iframe = document.getElementById('replay_iframe');
function unloadHandler(e) {
// Timeout needed because the URL changes immediately after
// the `unload` event is dispatched.
setTimeout(function () {
let splitUrl = iframe.contentWindow.location.href.split('mp_/');
if (splitUrl.length < 2) {
return;
}
let message = {
url: splitUrl.filter((x, i) => { return i > 0 }).join('mp_/'),
ts: splitUrl[0].split('/').pop(),
wb_type: 'unload'
};
window.postMessage(message);
}, 0);
};
function attachUnload() {
// Remove the unloadHandler in case it was already attached.
// Otherwise, the change will be dispatched twice.
iframe.contentWindow.removeEventListener("unload", unloadHandler);
iframe.contentWindow.addEventListener("unload", unloadHandler);
}
iframe.addEventListener("load", attachUnload);