From a web page on from Firefox Browser’s Add-ons site or the Chrome Web Store …
Open up the Developer Tools > Console, and copy-paste this snippet below:
1(function () {
2 function getExtName() {
3 const ogTitle = document.querySelector(
4 'meta[property="og-title"]'
5 )?.content; // Firefox
6 const microformatName = document.querySelector(
7 'meta[itemprop="name"]'
8 )?.value; // New Chrome
9 const schemaDotOrgName = JSON.parse(
10 document.querySelector('script[type="application/ld+json"]')?.innerHTML
11||
12 "{}"
13 )?.name; // Old Chrome
14 const title = `${
15 microformatName || schemaDotOrgName || ogTitle || document.title
16 }`
17 .trim()
18 .replace(/ - .*$/, "")
19 .replace(/ – .*$/, "")
20 .trim();
21 }
22
23 function saveAs(blob, name, type) {
24 const newBlob = new Blob([blob], {
25 type: type || "application/octet-stream",
26 });
27
28 if (window.navigator && window.navigator.msSaveOrOpenBlob) {
29 window.navigator.msSaveOrOpenBlob(newBlob, name);
30 return;
31 }
32
33 const data = window.URL.createObjectURL(newBlob);
34 const link = document.createElement("a");
35 link.href = data;
36 console.log("dataa", data, name);
37 link.download = name;
38 link.dispatchEvent(new MouseEvent("click"));
39 link.click();
40 setTimeout(() => {
41 URL.revokeObjectURL(data);
42 }, 3000);
43 }
44
45 const parseUrl = (url) =>
46 url instanceof URL ? url : new URL(url, window.location.origin);
47
48 function saveLink(url, overrides = {}) {
49 const { origin, href, pathname, protocol } = parseUrl(url);
50 const safeFn = href.split("//")[1].replace("/", "__");
51 const currentExtension = pathname.split(".").slice(-1)[0];
52 const newExtension =
53 overrides && "extension" in overrides ? overrides.extension : "";
54 const anchor = document.createElement("a");
55 anchor.style = "display:none !important";
56 anchor.id = `__extdl_${Math.random()}__`;
57 console.log({ newExtension, safeFn, currentExtension });
58 if ("download" in anchor) {
59 anchor.download = safeFn;
60 if (newExtension) {
61 const safeExtension = overrides.extension.replace(".", "");
62 anchor.download = `${safeFn.substr(
63 0,
64 safeFn.lastIndexOf(".")
65 )}.${safeExtension}`;
66 }
67 }
68 anchor.href = href;
69 document.body.appendChild(anchor);
70 setTimeout(() => {
71 anchor.click();
72 anchor.remove();
73 }, 100);
74 }
75
76 function saveExtBySelector(selector, href, overrides) {
77 const dlUrl = href || document.querySelector(selector)?.href;
78 if (!dlUrl) {
79 console.warn(`Could not find download link by $('${selector}') on
80page`);
81 return;
82 }
83 const parsedDlUrl = new URL(
84 dlUrl,
85 window.location.origin || "https://fake.ng"
86 );
87 console.log(`Downloading ${parsedDlUrl} …`);
88 saveLink(parsedDlUrl, overrides);
89 saveLink(parsedDlUrl, { extension: ".zip" });
90 const extName = getExtName();
91 alert(`Downloading ${extName} …`);
92 return parsedDlUrl;
93 }
94
95 function saveFirefoxExt(url, overrides) {
96 return saveExtBySelector("[href*='.xpi']", url, overrides);
97 }
98
99 function saveChromeExt(url, overrides) {
100 return saveExtBySelector("[href*='.crx']", url, overrides);
101 }
102
103 function saveFirefoxExtMeta(url, overrides = {}) {
104 const { origin, href, pathname, protocol } = parseUrl(url);
105 const extName = getExtName();
106 const safeFn = href.split("//")[1].replace("/", "__");
107 const targetUrl = `data:text/html,<a href="${
108 window.location.href
109 }">${extName}</a>
110 <p>saved to <code>${safeFn}.meta.json</code></p>
111 <pre>
112 ${JSON.stringify(meta, null, 2)}
113 </pre>`;
114
115 saveAs(
116 `${JSON.stringify(meta, null, 2)}`,
117 `${safeFn}.meta.json`,
118 "data:application/json"
119 );
120
121 setTimeout(() => {
122 self.window.top.close();
123 }, 10000);
124 setTimeout(() => {
125 window.location.href = targetUrl;
126 }, 5000);
127 }
128
129 function downloadExtension(url, overrides) {
130 saveFirefoxExt(url, overrides);
131 // const firefoxExtUrl = saveFirefoxExt(url, overrides);
132 // saveFirefoxExtMeta(firefoxExtUrl, overrides);
133 saveChromeExt(url, overrides);
134 }
135
136 downloadExtension(window.location.href);
137})();