您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
trace browsing history and preserve tables (HTML passthrough)
当前为
// ==UserScript== // @name MemTrace // @namespace Violentmonkey Scripts // @version 0.1 // @description trace browsing history and preserve tables (HTML passthrough) // @author fankaidev // @match *://*/* // @exclude *://cubox.pro/* // @exclude *://localhost:*/* // @exclude *://127.0.0.1:*/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @require https://cdnjs.cloudflare.com/ajax/libs/turndown/7.1.1/turndown.min.js // @require https://unpkg.com/[email protected]/dist/turndown-plugin-gfm.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/purify.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/crypto-js.js // @require https://cdn.jsdelivr.net/npm/@mozilla/[email protected]/Readability.min.js // @license MIT // ==/UserScript== (function () { "use strict"; function md5(input) { return CryptoJS.MD5(input).toString(); } let hrefHistory = []; // Function to get or initialize global state function getGlobalState(key, defaultValue) { return GM_getValue(key, defaultValue); } // Function to update global state function updateGlobalState(key, value) { GM_setValue(key, value); } // Function to get the endpoint function getEndpoint() { let endpoint = getGlobalState('endpoint', null); if (!endpoint) { endpoint = prompt("Please enter the endpoint URL:", "https://api.example.com/endpoint"); if (endpoint) { updateGlobalState('endpoint', endpoint); } else { console.error("MemTrace: No endpoint provided. Script will not function correctly."); } } return endpoint; } // Function to change the endpoint function changeEndpoint() { let newEndpoint = prompt("Enter new endpoint URL:", getGlobalState('endpoint', '')); if (newEndpoint) { updateGlobalState('endpoint', newEndpoint); console.log("MemTrace: Endpoint updated to", newEndpoint); } } // Register menu command to change endpoint GM_registerMenuCommand("Change MemTrace Endpoint", changeEndpoint); function process() { const url = window.location.href.split("#")[0]; if (hrefHistory.includes(url)) { return; } console.log("MemTrace: processing url", url); hrefHistory.push(url); const article = new Readability(document.cloneNode(true)).parse().content; console.log("article", article) const turndownService = new TurndownService({ keepReplacement: function (content, node) { return node.isBlock ? '\n\n' + node.outerHTML + '\n\n' : node.outerHTML; } }); // Add a rule to keep tables turndownService.addRule('tables', { filter: ['table'], replacement: function (content, node) { return node.outerHTML; } }); // Uncomment the following line if you want to use the GFM table plugin instead // turndownService.use(turndownPluginGfm.tables); let markdown = turndownService.turndown(article); if (markdown.length < 100) { console.log("MemTrace: fail to parse page"); return; } let data = { title: document.title, source: "chrome", id: md5(url), markdown: markdown, url: url, }; console.log("MemTrace: saving page", data); GM_xmlhttpRequest({ method: "POST", url: getEndpoint(), data: JSON.stringify(data), headers: { "Content-Type": "application/json", }, onload: function (response) { if (response.status === 200) { console.log("MemTrace: saved page"); } else { console.error("Failed to save to MemTrace", response.responseText); } }, onerror: function (error) { console.error("Request failed:", error); }, }); } window.addEventListener("load", function () { if (window.self === window.top) { setTimeout(() => { process(); }, 5000); } }); })();