// ==UserScript== // @name 【伟哥自用】脚本猫脚本站脚本下载助手 // @namespace https://bbs.tampermonkey.net.cn/ // @version 0.0.2 // @description 在脚本猫code页和diff页下载源码 (哥哥,你也不想在下源码时安装脚本吧 // @author 朱焱伟 // @match https://scriptcat.org/script-show-page/* // @match https://scriptcat.org/script-show-page/*/code // @match https://scriptcat.org/script-show-page/*/diff?version1=*&version2=* // @exclude https://scriptcat.org/script-show-page/*/comment // @exclude https://scriptcat.org/script-show-page/*/issue // @icon https://scriptcat.org/assets/logo.png // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // ==/UserScript== (function() { 'use strict'; class BaseDownloader { getM1code() { return monaco.editor.getModel("inmemory://model/1").getValue() } getScriptName() { return document.querySelector("a[href*='script-show-page']").textContent } download(filename, content, contentType) { if (!contentType) contentType = 'application/octet-stream'; var a = document.createElement('a'); var blob = new Blob([content], { 'type': contentType }); a.href = window.URL.createObjectURL(blob); a.download = filename; a.click(); } } class DiffDownloader extends BaseDownloader{ #scriptName; #v1Name; #v2Name; constructor() { super() if(this.isDiffPage()) { this.#scriptName = this.getScriptName() this.#v1Name = this.concatUserjsName(this.#scriptName,this.getVersions().v1) this.#v2Name = this.concatUserjsName(this.#scriptName,this.getVersions().v2) } } isDiffPage() { return window.location.pathname.search('diff') != -1 } getv1leftcode() { return monaco.editor.getModel("inmemory://model/1").getValue() } getv2rightcode() { return monaco.editor.getModel("inmemory://model/2").getValue() } getVersions() { /* https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript */ const urlParams = new URLSearchParams(window.location.search) const paramv1 = urlParams.get('version1') const paramv2 = urlParams.get('version2') return { v1:paramv1, v2:paramv2 } } concatUserjsName(codename,version){ return codename + 'v' + version +'.user.js' } v1download() { if(this.isDiffPage()) { this.download(this.#v1Name, monaco.editor.getModel("inmemory://model/1").getValue()) } } v2download() { if(this.isDiffPage()) { /** https://stackoverflow.com/questions/56970253/ace-editor-cannot-read-property-getvalue-of-undefined * this作用域的问题 */ this.download(this.#v2Name, monaco.editor.getModel("inmemory://model/2").getValue()) } } } class CodePageDownloader extends BaseDownloader{ #userJsName; constructor(){ super() if(this.isCodePage()){ this.#userJsName = this.concatUserjsName() } } isCodePage() { return window.location.pathname.search('code') != -1 } getScriptCode(){ return this.getM1code() } concatUserjsName(){ return this.getScriptName() + '.user.js' } scriptDownload(){ if(this.isCodePage()){ this.download(this.#userJsName,this.getScriptCode()) } } } /** * https://bbs.tampermonkey.net.cn/thread-1726-1-1.html * 如何做到当浏览器地址栏中的url变化后重新加载脚本?(出处: 油猴中文网) */ function onRouterChange(callback){ var _wr = function (type) { var orig = history[type]; return function () { var rv = orig.apply(this, arguments); var e = new Event(type); e.arguments = arguments; window.dispatchEvent(e); return rv; }; }; history.pushState = _wr('pushState'); window.addEventListener('pushState',callback); } var menu ={ code:null,/* code页面菜单id */ v1:null, /* diff页面version1菜单id */ v2:null /* diff页面version2菜单id */ } function flushMenu(){ const flushMenuByid = (menu_id) =>{ if(menu_id){ GM_unregisterMenuCommand(menu_id) } } flushMenuByid(menu.v1) flushMenuByid(menu.v2) flushMenuByid(menu.code) Object.keys(menu).forEach(key=>{menu[key]=null}) /* menu.v1等一个个用=null的方式经测试不能改变其值 */ } function addDownloadMenu(){ /* 分别在code页面和diff页面添加菜单,下载代码 */ if (window.location.pathname.search('code') != -1) {// code menu.code = GM_registerMenuCommand ("点我下载Code页代码", function(){ let codePageDownloader = new CodePageDownloader() codePageDownloader.scriptDownload() },'code'); } if (window.location.pathname.search('diff') != -1) {// diff let diffDownloader = new DiffDownloader() if (menu.v1 == null) { menu.v1 = GM_registerMenuCommand ("点我下载左侧代码",()=>{ diffDownloader.v1download() },'version1'); } if (menu.v2 == null) { menu.v2 = GM_registerMenuCommand ("点我下载右侧代码",()=>{ diffDownloader.v2download() },'version2'); } } } addDownloadMenu() /* match时添加菜单 */ onRouterChange( () => { /* 若路由发生改变,销毁菜单后再建 */ flushMenu() /* console.log("flush之后Menu内部元素:"+menu.v1+menu.v2+menu.code) */ addDownloadMenu() }) // Your code here... })(); /** * code页测试地址 https://scriptcat.org/script-show-page/513/code * diff页测试地址 https://scriptcat.org/script-show-page/57/diff?version1=66.93&version2=66.92 */