Skip to content

How to execute a user script before a page is saved

Gildas edited this page Oct 1, 2019 · 38 revisions
  1. Enable the hidden option userScriptEnabled by exporting the settings from the options page, editing the JSON file, replacing userScriptEnabled: false with userScriptEnabled: true, and importing the modified file in SingleFile.

  2. Dispatch the custom event single-file-user-script-init in the user script.

dispatchEvent(new CustomEvent("single-file-user-script-init"));
  1. Listen to the custom event single-file-on-before-capture-request in the user script. The listener function is called just before the page is saved.
addEventListener("single-file-on-before-capture-request", () => {
  console.log("The page will be saved by SingleFile");
});

If the listener function has to be async, call event.preventDefault() and dispatch the custom event single-file-on-before-capture-response once the asynchronous tasks are terminated.

addEventListener("single-file-on-before-capture-request", async event => {
  event.preventDefault();
  try {
    await ...
  } finally {
    dispatchEvent(new CustomEvent("single-file-on-before-capture-response"));
  }
});
  1. Listen to the custom event single-file-on-after-capture-request in the user script to execute a script after the page is processed by SingleFile.
addEventListener("single-file-on-after-capture-request", () => {
  console.log("The page has been processed by SingleFile");
});

Like single-file-on-before-capture-request, you can call event.preventDefault() and dispatch the custom event single-file-on-after-capture-response if the listener is an async function.

  1. The complete example below shows how to remove images from the page just before saving it and restoring them after the page is processed.
// ==UserScript==
// @name         Remove images
// @namespace    https://github.com/gildas-lormeau/SingleFile
// @version      1.0
// @description  [SingleFile] Remove all the images
// @author       Gildas Lormeau
// @match        *://*/*
// @noframes
// @grant        none
// ==/UserScript==


(() => {

  const elements = new Map();
  const removedElementsSelector = "img";
  dispatchEvent(new CustomEvent("single-file-user-script-init"));

  addEventListener("single-file-on-before-capture-request", () => {
    document.querySelectorAll(removedElementsSelector).forEach(element => {
      const placeHolderElement = document.createElement(element.tagName);
      elements.set(placeHolderElement, element);
      element.parentElement.replaceChild(placeHolderElement, element);
    });
  });

  addEventListener("single-file-on-after-capture-request", () => {
    Array.from(elements).forEach(([placeHolderElement, element]) => {
      placeHolderElement.parentElement.replaceChild(element, placeHolderElement);
    });
    elements.clear();
  });

})();

Note: To use this feature with SingleFileZ, use single-filez- instead of single-file- as a prefix for event names (e.g. single-filez-user-script-init).