Skip to content

Suggestion: Post message on 'unload' event #76

@VascoRatoFCCN

Description

@VascoRatoFCCN

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);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions