您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enable a unlimited favourite list
// ==UserScript== // @name Luogu Favorites // @namespace http://tampermonkey.net/ // @version v2.6.0 // @description Enable a unlimited favourite list // @author limesarine // @match https://www.luogu.com.cn/* // @license © 2024 Limesarine. All rights reserved. // @icon https://www.google.com/s2/favicons?sz=64&domain=luogu.com.cn // @grant none // ==/UserScript== (function() { 'use strict'; let Pflag=false,Fflag=false; if(localStorage.limesarine_favourite){} else { localStorage.limesarine_favourite="{}"; } let tmp=JSON.parse(localStorage.limesarine_favourite); delete tmp.list; localStorage.limesarine_favourite=JSON.stringify(tmp); const observer=new MutationObserver(function(mutationsList,observer){ setTimeout(function() { const url=document.URL; let Pmatches=url.match(/problem\/([A-Z][A-Za-z0-9_]+)$/); if(Pmatches && !Pflag) { Pflag=true; let title=""; let spanElements=document.getElementsByTagName("span"); for(let i=0;i<spanElements.length;i++) { let spanElement=spanElements[i]; let titleValue=spanElement.getAttribute("title"); if(titleValue && titleValue!=Pmatches[1]) { title=titleValue; } } if(title.startsWith(Pmatches[1])) { title=title.substr(Pmatches[1].length+1); } let now=JSON.parse(localStorage.limesarine_favourite)[Pmatches[1]]; console.log(Pmatches[1],title); let newScript=document.createElement("script"); newScript.innerHTML=` function limesarine_add_to_favourite(pid,title) { let dict=JSON.parse(localStorage.limesarine_favourite); dict[pid]=decodeURI(title); localStorage.limesarine_favourite=JSON.stringify(dict); alert('加入成功!'); location.reload(); } function limesarine_delete_from_favourite(pid) { let dict=JSON.parse(localStorage.limesarine_favourite); delete dict[pid]; localStorage.limesarine_favourite=JSON.stringify(dict); alert('删除成功!'); location.reload(); } `; document.head.appendChild(newScript); let newButton=document.createElement("button"); newButton.setAttribute("type","button"); newButton.setAttribute("data-v-7ade990c", ""); newButton.setAttribute("data-v-1fbfa3c2", ""); newButton.setAttribute("data-v-2dfcfd35", ""); newButton.setAttribute("class","lfe-form-sz-middle"); if(now) { newButton.setAttribute("style","border-color: rgba(255, 255, 255, 0.5); color: rgb(255, 255, 255); background-color: rgba(0, 0, 0, 0.5);"); newButton.setAttribute("onclick","limesarine_delete_from_favourite('"+Pmatches[1]+"');"); newButton.innerHTML="移出计划"; } else { newButton.setAttribute("style","border-color: rgb(52, 152, 219); background-color: rgb(52, 152, 219);"); newButton.setAttribute("onclick","limesarine_add_to_favourite(\""+Pmatches[1]+"\",\""+encodeURI(title)+"\");"); newButton.innerHTML="加入计划"; } let element=document.getElementsByClassName('lfe-form-sz-middle')[0]; element.parentNode.insertBefore(newButton,element.nextSibling); } else if((url=="https://www.luogu.com.cn" || url=="https://www.luogu.com.cn/") && !Fflag) { Fflag=true; let newArticle=document.createElement("div"); newArticle.setAttribute("class","lg-article"); newArticle.innerHTML="<h2>做题计划</h2>"; let newScript=document.createElement("script"); newScript.innerHTML=` async function limesarine_clear() { localStorage.limesarine_favourite="{}"; alert('清空成功!') location.reload(); } async function limesarine_import_from_paste() { let pasteid=document.getElementById('limesarine_paste_no').value; let reply=await fetch('/paste/'+pasteid+'?_contentOnly'); let content=await reply.text(); let json=await JSON.parse(content); localStorage.limesarine_favourite=json.currentData.paste.data; alert('导入成功!') location.reload(); } async function limesarine_export_to_paste() { let pasteid=document.getElementById('limesarine_paste_no').value; let response=await fetch("/paste/edit/"+pasteid, { headers: [ ["content-type", "application/json"], ["referer", "https://www.luogu.com.cn/"], ["x-csrf-token", document.querySelector("meta[name=csrf-token]").content], ], body: JSON.stringify({ data: localStorage.limesarine_favourite, id: pasteid, public: true, time: Math.floor(Date.now()/1000), }), method: "POST", }); response=await response.text(); alert('导出成功!'); } `; document.head.appendChild(newScript); let savedFavourites=JSON.parse(localStorage.limesarine_favourite); for(let i in savedFavourites) { newArticle.innerHTML+='<div class="tasklist-item" data-pid="'+i+'"><a class="colored" style="padding-left: 3px" href="/problem/'+i+'" target="_blank"><b>'+i+'</b> '+savedFavourites[i]+'</a></div>'; } newArticle.innerHTML+=` <p><input type="text" class="am-form-field" placeholder="云剪贴板编号" id="limesarine_paste_no"></input></p> <p> <button class="am-btn am-btn-danger am-btn-sm" onclick="limesarine_import_from_paste();">导入</button> <button class="am-btn am-btn-primary am-btn-sm" onclick="limesarine_export_to_paste();">导出</button> <button class="am-btn am-btn-sm am-btn-success" onclick="limesarine_clear();">清空</button> </p> <div><small>我们提供从云剪贴板导入和导出到云剪贴板的功能。注意,导入操作将覆盖当前做题计划,请谨慎使用!</small></div> `; let element=document.getElementsByClassName('lg-article')[3]; element.parentNode.insertBefore(newArticle,element); console.log(newArticle); } }, 750); }); observer.observe(document,{childList:true,subtree:true}); })();