您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
来自地板带着爱,记录上网冲浪的美好瞬间
当前为
// ==UserScript== // @name hipda-ID笔记 // @namespace http://tampermonkey.net/ // @version 0.2.1 // @description 来自地板带着爱,记录上网冲浪的美好瞬间 // @author 屋大维 // @license MIT // @match https://www.hi-pda.com/forum/viewthread.php?tid* // @resource IMPORTED_CSS https://code.jquery.com/ui/1.13.0/themes/base/jquery-ui.css // @require https://code.jquery.com/jquery-3.4.1.min.js // @require https://code.jquery.com/ui/1.13.0/jquery-ui.js // @icon https://icons.iconarchive.com/icons/iconshock/real-vista-project-managment/64/task-notes-icon.png // @grant GM.setValue // @grant GM.getValue // @grant GM.deleteValue // @grant GM_getResourceText // @grant GM_addStyle // ==/UserScript== (async function() { 'use strict'; // CSS const my_css = GM_getResourceText("IMPORTED_CSS"); GM_addStyle(my_css); GM_addStyle(".no-close .ui-dialog-titlebar-close{display:none} textarea{height:100%;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}"); // Your code here... // helpers function htmlToElement(html) { var template = document.createElement('template'); html = html.trim(); // Never return a text node of whitespace as the result template.innerHTML = html; return template.content.firstChild; } // classes class HpPost { constructor() { } getPostTid() { return location.href.match(/tid=(\d+)/) ? parseInt(location.href.match(/tid=(\d+)/)[1]) : -999; } getUserUid() { return parseInt($("cite > a").attr("href").split("uid=")[1]); } getHpThreads() { let postTid = this.getPostTid(); let divs = $('#postlist > div').get(); return divs.map(d => new Hpthread(postTid, d)); } addNoteManagementUI(_notebook) { var that = this; var button = htmlToElement(` <button id="noteButton_management"> <span><img src="https://icons.iconarchive.com/icons/iconshock/real-vista-project-managment/32/task-notes-icon.png"></img></span> </button> `); // create dialog let dialog = htmlToElement(` <div id="noteDialog_management" style="display: none;"> <h3>hipda-ID笔记 v${GM_info.script.version}</h3> <p style="margin: 10px auto 10px auto;">来自地板带着爱</p> <div> <button id="noteButton_import">导入</button> <button id="noteButton_export">导出</button> <button id="noteButton_reset">重置</button> </div> </div> `); $("body").append(dialog); $(document).ready( function () { $(document).on ("click", "#noteButton_import", function() { let r = confirm("确定要导入ID笔记吗?现有笔记将会被覆盖!"); if (!r) { return; } // prompt cannot handle large file, extend it in the future let data = prompt("请将 id笔记.json 中的文本复制粘贴入文本框:"); if (data !== null) { // try to load try { let j = JSON.parse(data); _notebook.importNotebook(j); } catch(err) { alert("格式错误!" + err); return; } alert("导入成功!"); } }); $(document).on ("click", "#noteButton_export", function() { let r = confirm("确定要导出ID笔记吗?"); if (!r) { return; } let a = document.createElement("a"); a.href = "data:text," + _notebook.exportNotebook(); a.download = "id笔记.json"; a.click(); }); $(document).on ("click", "#noteButton_reset", function() { let r = confirm("确定要清空ID笔记吗?"); if (!r) { return; } _notebook.resetNotebook(); alert("ID笔记已经清空!"); }); $(document).on ("click", `#noteButton_management`, function () { console.log("open notebook management dialog"); $(`#noteDialog_management`).dialog({ title: "ID笔记:管理面板", height: 150, width: 300, closeOnEscape: true, }); }); }); // add UI let d = $("td.modaction").last(); d.append(button); } } class Hpthread { constructor(postTid, threadDiv) { this.postTid = postTid; this._thread_div = threadDiv; } getThreadAuthorName() { return $(this._thread_div).find("div.postinfo > a").first().text(); } getThreadAuthorUid() { return parseInt($(this._thread_div).find("div.postinfo > a").first().attr("href").split("uid=")[1]); } getThreadPid() { return parseInt($(this._thread_div).attr("id").split("_")[1]); } getGotoUrl() { return `https://www.hi-pda.com/forum/redirect.php?goto=findpost&ptid=${this.postTid}&pid=${this.getThreadPid()}`; } getThreadContent() { // get text without quotes let t = $(this._thread_div).find("td.t_msgfont").first().clone(); t.find('.quote').remove(); return t.text().trim(); } getThreadBrief(n) { let content = this.getThreadContent(); if (content.length <= n) { return content; } return content.slice(0, n) + "\n\n【以上为截取片段】" ; } addNoteUI(_notebook) { let uid = this.getThreadAuthorUid(); let index = $(this._thread_div).index(); let userName = this.getThreadAuthorName(); var that = this; // create an UI element which contains data and hooks // button let button = htmlToElement(` <button id="noteButton_${index}" style="color:grey; margin-left:20px;"> ID笔记 </button> `); // note dialog let dialog = htmlToElement(` <div id="noteDialog_${index}" style="display: none;"> <textarea rows="10" wrap="hard" placeholder="暂时没有笔记"> </div> `); $("body").append(dialog); // add event to button $(document).ready( function () { $(document).on ("click", `#noteButton_${index}`, function () { console.log("open note for", userName); // freshly fetched from DB $(`#noteDialog_${index}`).find('textarea').first().val(_notebook.get(uid)); $(`#noteDialog_${index}`).dialog({ title: `ID笔记:${userName}`, dialogClass: "no-close", closeText: "hide", closeOnEscape: true, height: 350, width: 600, buttons: [ { text: "插入当前楼层", click: function() { let txt = $(`#noteDialog_${index}`).find('textarea').first(); var caretPos = txt[0].selectionStart; var textAreaTxt = txt.val(); var txtToAdd = `====\n引用: ${that.getGotoUrl()}\n${that.getThreadAuthorName()} 说:${that.getThreadBrief(200)}\n====`; txt.val(textAreaTxt.substring(0, caretPos) + txtToAdd + textAreaTxt.substring(caretPos) ); } }, { text: "确认", click: function() { // save the new note before close let newNote = $(`#noteDialog_${index}`).find('textarea').first().val(); _notebook.put(uid, userName, newNote); $(this).dialog( "close" ); } }, { text: "取消", click: function() { // close without saving $(this).dialog( "close" ); } } ] }); }); }); // add UI let d = $(this._thread_div).find("td[rowspan='2'].postauthor").first(); d.append(button); } } class Notebook { constructor(user_uid) { // initialization this._name = "hipda-notebook"; this._user_uid = user_uid; this._notebook = {}; return (async () => { this.loadFromLocalStorage(); return this; })(); } async loadFromLocalStorage() { console.log("load ID Notebook from Local Storage"); let data = await GM.getValue(this._name, null); if (data !== null) { this._notebook = JSON.parse(data); } } async saveToLocalStorage() { console.log("save ID Notebook to Local Storage"); await GM.setValue(this._name, JSON.stringify(this._notebook)); } put(uid, userName, note) { // we need userName here, so user can analyze notes even after export this._notebook[uid] = {uid, userName, note}; this.saveToLocalStorage(); } get(uid) { if (uid in this._notebook) { return this._notebook[uid].note; } return ""; } delete(uid) { if (uid in this._notebook) { delete this._notebook[uid]; this.saveToLocalStorage(); } } exportNotebook() { // can add meta data here let output = { notebook: this._notebook, version: GM_info.script.version, timestamp: + new Date() }; return JSON.stringify(output); } importNotebook(input) { let attrs = ['notebook', 'version', 'timestamp']; for (let i=0; i<attrs.length; i++) { if (!input.hasOwnProperty(attrs[i])) { throw(`bad format: ${attrs[i]} does not exist`); } } this._notebook = {...input.notebook}; this.saveToLocalStorage(); } resetNotebook() { this._notebook = {}; this.saveToLocalStorage(); } } // get a post object var THIS_POST = new HpPost(); // get tid and uid; uid for future extension var tid = THIS_POST.getPostTid(); var uid = THIS_POST.getUserUid(); var notebook = await new Notebook(uid); // render UI below // ID notes var hp_threads = THIS_POST.getHpThreads(); for (let i=0; i<hp_threads.length; i++) { let hp_thread = hp_threads[i]; hp_thread.addNoteUI(notebook); } // management panel THIS_POST.addNoteManagementUI(notebook); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址