您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A simple script to add buttons on login that let you save and load logs into your browser storage.
// ==UserScript== // @name F-List log saver // @namespace http://tampermonkey.net/ // @version 1.0 // @description A simple script to add buttons on login that let you save and load logs into your browser storage. // @author DD // @match https://www.f-list.net/chat3/ // @grant none // ==/UserScript== (function() { const userscript = document.createElement("script"); userscript.innerHTML = ` const saveLogs=() => { ////////////////////////////////////////////////////////////////////////// // Parse Local Storage ////////////////////////////////////////////////////////////////////////// const keyList = Object.keys(window.localStorage); let storageContent = []; let completeJSON = {saved_dbs: {}}; for(let key of keyList){ storageContent.push(JSON.parse('{ "key":"' + key + '", "value":"" }')) } for(let key of storageContent){ key.value = JSON.parse(window.localStorage.getItem(key.key)); } completeJSON.saved_dbs.local_storage = storageContent; ////////////////////////////////////////////////////////////////////////// // Parse IndexedDB ////////////////////////////////////////////////////////////////////////// storageContent = {}; let databaseLoopIndex = 0; indexedDB.databases().then(databaseList =>{ for(let database of databaseList){ const dataBaseLoop=(db, index)=>{ let dbConnection; let request = window.indexedDB.open(db.name, db.version); request.onerror=(event) =>{ console.log('Error on connect to "'+db.name+'" : ' + event.target.errorCode); }; request.onsuccess=(event) =>{ dbConnection = event.target.result; console.log('Connection to "'+db.name+'" established!'); let databaseObject = {}; let storeIndex = 0; for(let storeName of dbConnection.objectStoreNames){ const objectStoreLoop=(pStoreName, pStoreIndex, databaseIndex)=>{ databaseObject[pStoreName] = []; let transaction = dbConnection.transaction([pStoreName]); transaction.oncomplete=(event) =>{ console.log('Transaction finished on "' + pStoreName); if(pStoreIndex === dbConnection.objectStoreNames.length - 1 && databaseIndex === databaseList.length - 1){ function downloadObjectAsJson(exportObj, exportName){ var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportObj)); var downloadAnchorNode = document.createElement('a'); downloadAnchorNode.setAttribute("href", dataStr); downloadAnchorNode.setAttribute("download", exportName + ".json"); document.body.appendChild(downloadAnchorNode); // required for firefox downloadAnchorNode.click(); downloadAnchorNode.remove(); console.log("Saved successfully!") } console.log(completeJSON); downloadObjectAsJson(completeJSON, "f-list-log"); } }; transaction.onerror=(event)=>{ console.log('Transaction-Error: ' + event.target.errorCode); }; transaction.objectStore(pStoreName).getAll().onsuccess=(event) =>{ databaseObject[pStoreName] = event.target.result; } } objectStoreLoop(storeName, storeIndex, index); storeIndex++; }; storageContent[db.name] = databaseObject; }; } dataBaseLoop(database, databaseLoopIndex); databaseLoopIndex++; } }); completeJSON.saved_dbs.indexed_db = storageContent; } const loadLogs=(e)=>{ const file = e.target.files[0]; if (!file) { return; } const reader = new FileReader(); reader.onload = function(e) { const contents = e.target.result; const totalJSONObject = JSON.parse(contents); console.log(totalJSONObject); ////////////////////////////////////////////////////////////////////////// // load Local Storage ////////////////////////////////////////////////////////////////////////// for(let entry of totalJSONObject.saved_dbs.local_storage){ window.localStorage.setItem(entry.key, JSON.stringify(entry.value)); } ////////////////////////////////////////////////////////////////////////// // load IndexedDB ////////////////////////////////////////////////////////////////////////// let databaseLoopIndex = 0; const databaseList = Object.keys(totalJSONObject.saved_dbs.indexed_db); // Need to parse the datestrigns properly into dates for(let databaseName of databaseList){ for(let entry of totalJSONObject.saved_dbs.indexed_db[databaseName].logs){ entry.time = new Date(entry.time); } } console.log(totalJSONObject); for(let database of databaseList){ const dataBaseLoop=(dbName)=>{ let request = window.indexedDB.open(dbName, 1); request.onerror=(event) =>{ console.log('Error on connect to "'+dbName+'" : ' + event.target.errorCode); }; request.onsuccess=(event) =>{ const dbConnection = event.target.result; console.log('Connection to "'+dbName+'" established!'); let storeIndex = 0; for(let storeName of dbConnection.objectStoreNames){ const objectStoreLoop=(pStoreName)=>{ const transaction = dbConnection.transaction(pStoreName, "readwrite"); transaction.oncomplete=(event) =>{ console.log('Transaction finished on "' + pStoreName); }; transaction.onerror=(event)=>{ console.log('Transaction-Error: ' + event.target.errorCode); }; // transaction.objectStore(pStoreName).getAll().onsuccess=(event) =>{ // } const objectStoreArray = totalJSONObject.saved_dbs.indexed_db[dbName][pStoreName]; let objectStore = transaction.objectStore(pStoreName); objectStoreArray.forEach(element => { objectStore.put(element).onsuccess=(event) => {} }); } objectStoreLoop(storeName); storeIndex++; }; }; request.onupgradeneeded=(event) => { const dbConnection = event.target.result; dbConnection.createObjectStore("conversations", {autoIncrement: true, keyPath: "id"}); const objectStore = dbConnection.createObjectStore("logs", {autoIncrement: true, keyPath: "id"}); objectStore.createIndex("conversation", "conversation", {unique: false}); objectStore.createIndex("conversation-day", ["conversation", "day"], {unique: false}); } } dataBaseLoop(database); databaseLoopIndex++; } }; reader.readAsText(file); } ////////////////////////////////////////////////////////////////////////// // Insert buttons ////////////////////////////////////////////////////////////////////////// let cardHeader = document.getElementsByClassName("card-body")[0].childNodes[2]; // Execute the code only when connected if(cardHeader){ // Show the buttons on the page for Saving and Loading let btn_load = document.createElement("input"); let btn_save = document.createElement("button"); btn_save.setAttribute("class", "btn btn-primary"); btn_save.innerText = "Save Logs"; btn_save.setAttribute("onclick", "saveLogs()"); cardHeader.appendChild(btn_save); // btn_load.setAttribute("class", "btn btn-primary"); btn_load.innerText = "Load Logs"; btn_load.setAttribute("type", "file"); btn_load.setAttribute("id", "btn_load"); cardHeader.appendChild(btn_load); document.getElementById('btn_load') .addEventListener('change', loadLogs, false); } `; document.getElementsByTagName("html")[0].appendChild(userscript); })();