Search code examples
javascripthtmlgoogle-chrome-extensionhtml5-history

How do I save the page state with JavaScript execution results and restore it later?


I'm developing a chrome extension for YouTube. The extension writes alternative subtitles with different behavior. The subtitle file is taken from YouTube by the link.

In order for me to be able to show subtitles by the time the video starts playing, I have to download the subtitle files before the video loads. At low Internet speed, JSON files of subtitles are loaded simultaneously with the YouTube page for a very long time.

I use this approach. To prevent my extension from competing with YouTube scripts, my extension:

  • calls window.stop() at the very beginning of page loading.
  • After stopping the download, I download the files I need.
  • Then the extension reloads the page.

But I would not want to reload the page if there are entries in window.history. Of course, I would just like to block the page rendering thread for example by window.renderPause() and then resume by window.renderResume(). I would not use window.stop(). But JavaScript does not provide such an opportunity. How do I save the page state with JavaScript execution results and restore it later? This code doesn't work for youtube. JavaScript of YouTube does not start.

let clonedHtml = document.documentElement.cloneNode(true);
let clonedWindow = Object.assign({}, window);
document.documentElement.innerHTML = "";
window = clonedWindow;
document.replaceChild(clonedHtml, document.documentElement);

I can not use window.history.back() or window.history.forward() because window.stop() does not allow to load a page.


Solution

  • Do you want to prevent the video from starting before your subtitle files are loaded? Restoring the page state itself will be very complex, there is no generic solution which works for all websites.

    To load your subtitles before youtube scripts load:

    • Use [chrome.webRequest.onBeforeRequest][1] and replace youtube's subtitle URL with your own subtitle URL (or replace the file content afterRequest)

    • Checkout this answer which hooks the page load event where you can fetch and inject your subtitles before anything else loads.

    Both methods won't require an additional page reload. [1]: https://developer.chrome.com/docs/extensions/reference/webRequest/