// ==UserScript== // @name 「水水」豆瓣助手 // @namespace https://www.wdssmq.com/ // @version 1.0.2 // @author 沉冰浮水 // @description 辅助删除日记什么的 // @license MIT // @null ---------------------------- // @contributionURL https://github.com/wdssmq#%E4%BA%8C%E7%BB%B4%E7%A0%81 // @contributionAmount 5.93 // @null ---------------------------- // @link https://github.com/wdssmq/userscript // @link https://afdian.net/@wdssmq // @link https://greasyfork.org/zh-CN/users/6865-wdssmq // @null ---------------------------- // @noframes // @run-at document-end // @match https://www.douban.com/people/*/notes* // @match http://localhost:3000/ // @grant none // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js // @require https://unpkg.com/sweetalert/dist/sweetalert.min.js // ==/UserScript== /* eslint-disable */ /* jshint esversion: 6 */ (function () { 'use strict'; const gm_name = "douban"; // 初始常量或函数 const curUrl = window.location.href; // ------------------------------------- const _curUrl = () => { return window.location.href }; // ------------------------------------- const _log = (...args) => console.log(`[${gm_name}] |`, ...args); const _warn = (...args) => console.warn(`[${gm_name}] |`, ...args); // ------------------------------------- const $ = window.$ || unsafeWindow.$; // localStorage 封装 const lsObj = { setItem: function (key, value) { localStorage.setItem(key, JSON.stringify(value)); }, getItem: function (key, def = "") { const item = localStorage.getItem(key); if (item) { return JSON.parse(item); } return def; }, }; // 数据读写封装 const gobInfo = { // key: [默认值, 是否记录至 ls] userAgreed: [false, true], keepList: [[], true], delList: [[], true], autoDel: [false, true], lstPageUrl: ["", true], // 运行时获取 infoList: [[], false], }; const gob = { _lsKey: `${gm_name}_data`, _bolLoaded: false, data: {}, // 初始 init() { // 根据 gobInfo 设置 gob 属性 for (const key in gobInfo) { if (Object.hasOwnProperty.call(gobInfo, key)) { const item = gobInfo[key]; this.data[key] = item[0]; Object.defineProperty(this, key, { // value: item[0], // writable: true, get() { return this.data[key] }, set(value) { this.data[key] = value; }, }); } } return this; }, // 读取 load() { if (this._bolLoaded) { return; } const lsData = lsObj.getItem(this._lsKey, this.data); _log("[log]gob.load()", lsData); for (const key in lsData) { if (Object.hasOwnProperty.call(lsData, key)) { const item = lsData[key]; this.data[key] = item; } } this._bolLoaded = true; }, // 保存 save() { const lsData = {}; for (const key in gobInfo) { if (Object.hasOwnProperty.call(gobInfo, key)) { const item = gobInfo[key]; if (item[1]) { lsData[key] = this.data[key]; } } } _log("[log]gob.save()", lsData); lsObj.setItem(this._lsKey, lsData); }, }; // 初始化 gob.init().load(); // 判断是否首次执行 const fnCheckFirst = () => { const { userAgreed } = gob; const fnNext = (bolAgree) => { if (bolAgree) { swal("请刷新网页使用脚本功能", "您已同意使用本脚本!", "success"); } else { swal("请刷新网页重新选择或删除脚本", "须在上一步点击「继续」方可使用!", "info"); } }; if (!userAgreed) { // 提示 swal({ icon: "warning", title: "注意! - 豆瓣助手", text: "请认真筛选要删除的日记,删除后无法恢复!", buttons: ["取消", "继续"], }).then((bolAgree) => { // _warn("fnCheckFirst", { bolAgree }); if (bolAgree) { gob.userAgreed = true; gob.save(); } fnNext(bolAgree); }); } }; const fnCheckKeep = (info) => { const { url } = info; const { keepList } = gob; const bolKeep = keepList.some(item => item.url === url); return bolKeep; }; const fnAddKeep = (info) => { const { keepList } = gob; keepList.push(info); gob.keepList = keepList; gob.save(); }; const fnSavePageUrl = () => { gob.lstPageUrl = curUrl; gob.save(); }; const fnCheckPageUrl = (goto = false) => { let { lstPageUrl } = gob; // 移除掉 &_i=xxx const curUrl = _curUrl().replace(/&_i=.+/, ""); lstPageUrl = lstPageUrl.replace(/&_i=.+/, ""); // 调试 _log("fnCheckPageUrl", { lstPageUrl, curUrl }); // 判断是已在缓存的页面 if (lstPageUrl === curUrl || !lstPageUrl) { return true; } if (goto && lstPageUrl) { window.location.href = lstPageUrl; return false; } // // 监听分页条点击,清除 lstPageUrl // $("div.paginator").on("click", "a", function (e) { // gob.lstPageUrl = ""; // gob.save(); // }); return false; }; const fnGetNotes = () => { const $$notes = $(".note-container"); // _log("fnGetNotes", $$notes); return $$notes; }; // 管理 infoList const fnUpInfoList = (noteInfo, i, act = "def") => { if ("keep" === act) { noteInfo.keep = true; noteInfo.$delBtn = null; } gob.infoList[i] = noteInfo; // _log("fnUpInfoList", gob.infoList); // gob.save(); return; }; // 对于保留的日记,简化显示 const fnSetKeepView = ($note, info) => { const tplKeep = "「保留」-title-"; $note.html(tplKeep .replace(/-url-/g, info.url) .replace(/-title-/g, info.title)); $note.addClass("note-keep"); return; }; const fnActDel = () => { // 延时控制 const intDely = 1000; const { delList, autoDel } = gob; // 判断并执行自动删除 if (autoDel && delList.length) { // 提取第一个 const noteInfo = delList.shift(); const $note = $(`#${noteInfo.id}`); const $delBtn = $note.find(".note-footer-stat-del a"); // 调试 // _log("fnActDel", { info, infoList: gob.infoList }); if ($note.length && $delBtn.length) { // 构造删除函数 const fnDel = () => { // 按钮样式及文本 $delBtn.text("删除中..."); $delBtn.css("color", "red"); setTimeout(() => { $delBtn[0].click(); }, intDely * 1.1); }; // // 判断是否在可视区域 // const bolInView = $note[0].getBoundingClientRect().top < window.innerHeight; // if (!bolInView) { // setTimeout(() => { // $note[0].scrollIntoView(); // }, intDely * .7); // } // 执行删除 fnDel(); } else { _warn("fnActDel", "not found $note or $delBtn"); } setTimeout(() => { gob.delList = delList; gob.save(); }, intDely); } else if (autoDel) { setTimeout(() => { $(".tip-cnt-down").text("完成"); }, intDely * .7); // 清除自动删除状态 gob.autoDel = false; gob.lstPageUrl = ""; gob.save(); } }; // 构建删除任务 const fnGenDelTask = () => { let { delList, infoList, autoDel } = gob; // 判断是否已有删除任务 if (delList.length) { _warn("fnGenDelTask", "delList.length > 0"); _warn("fnGenDelTask", { delList }); return; } // 保存当前页面地址 fnSavePageUrl(); // 生成删除任务 delList = infoList.filter(item => !item.keep); // 将删除以下日记,仅显示一次 if (!autoDel) { let msg = "删除以下日记,仅显示一次:\n"; _log("fnGenDelTask", { delList }); delList.forEach((item, i) => { msg += `${i + 1}. ${item.title}\n`; }); // 再次确认 const bolConfirm = confirm(msg); if (!bolConfirm) { return; } autoDel = true; } _log("fnGenDelTask", { delList, infoList }); // 保存 gob.delList = delList; gob.autoDel = autoDel; gob.save(); // 执行首个删除任务 fnActDel(); }; // 添加删除按钮 const fnAddDelBtn = ($note) => { const $usr = $("#db-usr-profile"); // 添加删除按钮 const tplDelBtn = "

自动删除

"; $usr.find(".info").after(tplDelBtn); const $delBtn = $usr.find(".auto-del-btn"); // 按钮状态 const fnActDelBtn = (autoDel = false) => { const { delList } = gob; if (autoDel) { const cntDown = delList.length + 1; $(".tip-cnt-down").text(`剩余 ${cntDown} 篇`); } $delBtn.text("执行中..."); $delBtn.addClass("del-btn-ing"); }; // 判断是否已有删除任务 if (gob.autoDel) { fnActDelBtn(true); } // 点击删除按钮 $delBtn.click(function () { // 询问是否删除 const bolConfirm = confirm("是否删除本页非保留状态的日记?"); if (bolConfirm) { fnActDelBtn(); fnGenDelTask(); } }); }; // 初始函数 const fnMngNotes = () => { const { userAgreed } = gob; // 判断是否已同意 if (!userAgreed) { return; } // 判断是否在缓存的页面 const bolPage = fnCheckPageUrl(true); if (!bolPage) { return; } // 执行已有删除任务 fnActDel(); // 获取元素 const $$notes = fnGetNotes(); // 遍历元素 $$notes.each(function (i) { // 元素节点 const $note = $(this); const $noteID = $note.attr("id"); const $noteTitle = $note.find("h3>a"); const $noteFooter = $note.find(".note-ft"); const $noteSNS = $note.find(".sns-bar"); const $delBtn = $note.find(".note-footer-stat-del a"); // 日志信息 const noteInfo = { id: $noteID, title: $noteTitle.text(), url: $note.data("url"), keep: false, $delBtn, }; // 判断 const bolKeep = fnCheckKeep(noteInfo); if (bolKeep) { fnUpInfoList(noteInfo, i, "keep"); fnSetKeepView($note, noteInfo); return; } else { fnUpInfoList(noteInfo, i); } // _log(gob.infoList); // 添加按钮用于设置保留 const tplKeep = "- 「设为保留」"; $noteTitle.after(tplKeep); // 点击保留按钮 $note.find(".keep-btn").click(function () { // const bolConfirm = confirm(`是否保留笔记:${noteInfo.title}`); // if (!bolConfirm) { // return; // } fnAddKeep(noteInfo); fnUpInfoList(noteInfo, i, "keep"); fnSetKeepView($note, noteInfo); }); // 隐藏时间 const $pubDate = $note.find(".pub-date").parent(); $pubDate.hide(); // 隐藏 SNS $noteSNS.before("
"); $noteSNS.hide(); // 显示删除按钮 $noteFooter.show().prepend("
"); // _log("noteInfo", noteInfo); }); // 添加删除按钮 fnAddDelBtn(); // _log(gob.data); }; fnCheckFirst(); fnMngNotes(); })();