-
-
Notifications
You must be signed in to change notification settings - Fork 1k
How to execute a user script before a page is saved
- When using SingleFile as:
- an extension, enable the hidden option
userScriptEnabled
by exporting the settings from the options page, editing the JSON file, replacinguserScriptEnabled: false
withuserScriptEnabled: true
, and importing the modified file in SingleFile. You will also need to install an extension to store and run user scripts (search "user script" on stores). - a CLI tool, use the option
--browser-script
to pass script path(s) to SingleFile.
- Dispatch the custom event
single-file-user-script-init
in the user script.
dispatchEvent(new CustomEvent("single-file-user-script-init"));
- 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"));
}
});
You can also get and set the options via the detail
property of the single-file-on-before-capture-request
and single-file-on-before-capture-response
events. If the detail
value is tainted (e.g. in Firefox), you should dispatch the single-file-user-script-init
event with { detail: "jsonDetail" }
as option. Then, you have to handle the detail
value as a JSON string (instead of an object).
- 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.
- Examples
- This script removes images from the page just before saving it and restores 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 *://*/*
// @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();
});
})();
- This script converts the title to kebab-case and restores it after the page is processed.
// ==UserScript==
// @name Convert title to kebab-case
// @namespace https://github.com/gildas-lormeau/SingleFile
// @version 1.0
// @description [SingleFile] Convert title to kebab-case
// @author Gildas Lormeau
// @match *://*/*
// @noframes
// @grant none
// ==/UserScript==
(() => {
let title;
dispatchEvent(new CustomEvent("single-file-user-script-init"));
addEventListener("single-file-on-before-capture-request", () => {
title = document.title;
document.title = document.title
.replace(/[^a-z0-9-\s]/gi, "")
.replace(/[-\s]+/g, "-")
.toLowerCase();
});
addEventListener("single-file-on-after-capture-request", () => {
document.title = title;
});
})();
- This script displays the page in reader mode (with readability.js) just before saving it: https://gist.github.com/gildas-lormeau/963f363bce2a7bdb53b46ec74e11bf5c