// ==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( [`${document.title}`], 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(); })();