下载当前网页的快捷链接文件
// ==UserScript==
// @name 下载当前网页的快捷链接文件
// @namespace https://github.com/AliubYiero/TamperMonkeyScripts
// @version 1.1.0
// @description 下载一个 html 文件, 快速链接到当前网页, 让本地可以快速打开网页
// @author Yiero
// @match *://*/*
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_info
// ==/UserScript==
/**
* 下载文件
*/
const downloadFile = (blob, filename) => {
const node = document.createElement('a');
node.download = filename;
node.href = URL.createObjectURL(blob);
node.click();
}
/**
* 下载当前网页的快捷链接文件
*/
const downloadLinkWebFile = () => {
const filename = `${document.title}.html`
// 创建 Blob
const htmlBlob = new File(
[`<!doctype html><html lang="zh"><head><meta charset="UTF-8"/><title>${document.title}</title><script>window.location.href = '${document.URL}'</script></head><body></body></html>`],
filename,
{ type: 'text/html' },
);
// 下载文件
downloadFile(htmlBlob, filename);
};
/**
* 油猴按钮管理器
*/
class RegisterMenu {
#title;
#callback;
#menuId;
constructor(title, callback) {
this.#title = title;
this.#callback = callback;
}
open() {
this.#menuId && this.close();
this.#menuId = GM_registerMenuCommand(this.#title, this.#callback)
}
close() {
GM_unregisterMenuCommand(this.#menuId)
}
}
/**
* 事件监听器管理器
*/
class EventListener {
#event;
#callback;
#storageKey;
constructor(storageKey, event, callback) {
this.#event = event;
this.#callback = callback;
this.#storageKey = storageKey;
};
open() {
GM_getValue(this.#storageKey) && this.close();
window.addEventListener(this.#event, this.#callback)
GM_setValue(this.#storageKey, true)
}
close() {
window.removeEventListener(this.#event, this.#callback)
GM_setValue(this.#storageKey, false)
}
getStat() {
return GM_getValue(this.#storageKey, false);
}
}
/**
* 判断当前页面是否为 iframe 页面.
*
* 防止在一个页面中因为多个 iframe 页面, 导致菜单选项重复触发从而导致异常.
*
* @return {boolean}
*/
const isIframe = () => {
return Boolean(
window.frameElement && window.frameElement.tagName === 'IFRAME'
|| window !== window.top
)
}
(function () {
'use strict';
// 判断当前页面是否为 iframe
if (isIframe()) {
return;
}
// 声明下载按钮
const downloadMenu = new RegisterMenu('download', downloadLinkWebFile);
downloadMenu.open();
// 将 Ctrl + S 绑定为快捷下载
const bindDownloadEvent = new EventListener('bindLinkSave', 'keydown', (e) => {
if (!(e.ctrlKey && e.code === 'KeyS')) {
return;
};
e.preventDefault();
downloadLinkWebFile()
})
// // 关闭 Ctrl+S 快捷下载
let openBindMenu;
let openCloseMenu;
openBindMenu = new RegisterMenu('[点击开启] 绑定Ctrl + S', () => {
openBindMenu.close();
openCloseMenu.open();
bindDownloadEvent.open();
})
// 将 Ctrl+S 绑定为下载
openCloseMenu = new RegisterMenu('[点击关闭] 绑定Ctrl + S', () => {
openCloseMenu.close();
openBindMenu.open();
bindDownloadEvent.close();
});
const openStat = bindDownloadEvent.getStat();
// 如果是开启状态, 绑定事件并且开启[关闭配置项]
if (openStat) {
bindDownloadEvent.open();
openCloseMenu.open();
return;
}
// 如果是关闭状态, 开启[开启配置项]
openBindMenu.open();
})();