/** HTML escape */ function escapeHtml(unsafe) { return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } /** Escape URL chars that could throw off the meta redirect tag */ function sanitizeUrl(unsafe) { return unsafe .replace(/;/g, "%3B"); } /** Remove the most risky characters from a filename string */ function cleanFilename(unsafe) { return unsafe .replace(/::/g, " - ") .replace(/[/\\?*|"'<>:]+/g, " ") .replace(/\s+/g, " ") .replace(/[\._-]$/g, "") .trim(); } browser.browserAction.onClicked.addListener((tab) => { const escapedUrl = escapeHtml(sanitizeUrl(tab.url)); const escapedTitle = escapeHtml(tab.title); const filename = cleanFilename(tab.title); console.log(`Escaped URL: "${escapedUrl}"`); console.log(`Escaped title: "${escapedTitle}"`); console.log(`Saving as: "${filename}"`); const html = ` ${escapedTitle} Redirecting to: ${escapedUrl} `; const content = new Blob([html]); //console.log(`Generated HTML:\n${html}`); browser.downloads.download({ filename: `${filename}.link.html`, url: URL.createObjectURL(content) }); });