您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds custom features to MSPFA.
当前为
// ==UserScript== // @name MSPFA extras // @namespace http://tampermonkey.net/ // @version 1.0 // @description Adds custom features to MSPFA. // @author seymour schlong // @match https://mspfa.com/* // @grant none // ==/UserScript== (function() { 'use strict'; const saveData = (data) => { localStorage.mspfaextra = JSON.stringify(data); console.log("Saved cookies under mspfaextra."); }; let settings = {}; if (localStorage.mspfaextra) { settings = JSON.parse(localStorage.mspfaextra); } else { settings.autospoiler = false; settings.style = 0; settings.styleURL = ""; saveData(settings); } let styleOptions = ["Standard", "Low Contrast", "Light", "Dark", "Felt", "Trickster", "Custom"]; let myLink = document.querySelector('nav a[href="/my/"]'); let dropdownDiv = document.createElement('div'); dropdownDiv.className = 'dropdown'; let dropdownContent = document.createElement('div'); dropdownContent.className = 'dropdown-content'; if (myLink) { myLink.parentNode.insertBefore(dropdownDiv, myLink); dropdownDiv.appendChild(myLink); dropdownDiv.appendChild(dropdownContent); let dLinks = []; dLinks[0] = [ 'Messages', 'My Adventures', 'Settings' ]; dLinks[1] = [ '/my/messages/', '/my/stories/', '/my/settings/' ]; for (let i = 0; i < dLinks[0].length; i++) { let newLink = document.createElement('a'); newLink.textContent = dLinks[0][i]; newLink.href = dLinks[1][i]; dropdownContent.appendChild(newLink); } } let dropdownStyle = document.createElement('style'); dropdownStyle.id = 'dropdown-style'; dropdownStyle.textContent = '#notification { z-index: 2;}.dropdown:hover .dropdown-content { display: block;}.dropdown { position: relative; display: inline-block;}.dropdown-content { display: none; position: absolute; text-align: left; background-color: #000000; min-width: 100px; margin-left: -5px; padding: 2px; z-index: 1; border-radius: 0 0 5px 5px;}.dropdown-content a { color: #fffa36; padding: 2px 2px; text-decoration: underline; display: block;}'; let theme = document.createElement('link'); theme.id = 'theme'; theme.type = "text/css"; theme.rel = "stylesheet"; if (!document.querySelector('#theme') || !/^\/css\/|^\/js\//.test(location.pathname)) { document.querySelector('head').appendChild(theme); } if (!document.querySelector('#dropdown-style')) { document.querySelector('head').appendChild(dropdownStyle); } theme.href = settings.style < styleOptions.length - 1 ? '/css/theme' + settings.style + '.css' : settings.styleURL; if (location.pathname === "/") { // Auto-open spoilers if (settings.autospoiler) { window.MSPFA.slide.push((p) => { document.querySelectorAll('#slide .spoiler:not(.open) > div:first-child > input').forEach(sb => sb.click()); }); } if (location.search) { let dateInterval = setInterval(() => { if (document.querySelector('#infobox tr td:nth-child(2)')) { document.querySelector('#infobox tr td:nth-child(2)').appendChild(document.createTextNode('Creation date: ' + new Date(window.MSPFA.story.d).toString().split(' ').splice(1, 3).join(' '))); clearInterval(dateInterval); } }, 500); } } else if (location.pathname === "/my/settings/") { // Custom settings let saveBtn = document.querySelector('#savesettings'); let table = document.querySelector("#editsettings tbody"); let saveTr = table.querySelectorAll("tr"); saveTr = saveTr[saveTr.length - 1]; let headerTr = document.createElement('tr'); let header = document.createElement('th'); header.textContent = "Extra Settings"; headerTr.appendChild(header); let settingsTr = document.createElement('tr'); let localMsg = document.createElement('span'); let settingsTd = document.createElement('td'); localMsg.innerHTML = "Because this is an extension, any data saved is only <b>locally</b> on this device.<br>Don't forget to <b>save</b> when you've finished making changes!"; let plusTable = document.createElement('table'); let plusTbody = document.createElement('tbody'); plusTable.appendChild(plusTbody); settingsTd.appendChild(localMsg); settingsTd.appendChild(document.createElement('br')); settingsTd.appendChild(document.createElement('br')); settingsTd.appendChild(plusTable); settingsTr.appendChild(settingsTd); let spoilerTr = plusTbody.insertRow(0); let spoilerTextTd = spoilerTr.insertCell(0); let spoilerInputTd = spoilerTr.insertCell(1); let spoilerInput = document.createElement('input'); spoilerInputTd.appendChild(spoilerInput); let cssTr = plusTbody.insertRow(1); let cssTextTd = cssTr.insertCell(0); let cssSelectTd = cssTr.insertCell(1); let cssSelect = document.createElement('select'); cssSelectTd.appendChild(cssSelect); let customTr = plusTbody.insertRow(2); let customTextTd = customTr.insertCell(0); let customCssTd = customTr.insertCell(1); let customCssInput = document.createElement('input'); customCssTd.appendChild(customCssInput); plusTable.style = "text-align: center;"; spoilerTextTd.textContent = "Automatically open spoilers:"; spoilerInput.name = "p1"; spoilerInput.type = "checkbox"; spoilerInput.checked = settings.autospoiler; cssTextTd.textContent = "Change style:"; customTextTd.textContent = "Custom CSS URL:"; customCssInput.style.width = "99px"; customCssInput.value = settings.styleURL; styleOptions.forEach(o => cssSelect.appendChild(new Option(o, o))); // Enable the save button spoilerInput.addEventListener("mouseup", () => { saveBtn.disabled = false; }); cssSelect.addEventListener("mouseup", () => { saveBtn.disabled = false; }); customCssInput.addEventListener("mouseup", () => { saveBtn.disabled = false; }); saveTr.parentNode.insertBefore(headerTr, saveTr); saveTr.parentNode.insertBefore(settingsTr, saveTr); cssSelect.selectedIndex = settings.style; saveBtn.addEventListener('mouseup', () => { settings.autospoiler = spoilerInput.checked; settings.style = cssSelect.selectedIndex; settings.styleURL = customCssInput.value; theme.href = settings.style < styleOptions.length - 1 ? '/css/theme' + settings.style + '.css' : settings.styleURL; console.log(settings); saveData(settings); }); } else if (location.pathname === "/my/messages/") { // New buttons let btnStyle = "margin: 10px 5px;"; // Select all read messages button. const selRead = document.createElement('input'); selRead.style = btnStyle; selRead.value = "Select Read"; selRead.id = "selectread"; selRead.classList.add("major"); selRead.type = "button"; // On click, select all messages with the style attribute indicating it as read. selRead.addEventListener('mouseup', () => { document.querySelectorAll('td[style="border-left: 8px solid rgb(221, 221, 221);"] > input').forEach((m) => m.click()); }); // Select duplicate message (multiple update notifications). const selDupe = document.createElement('input'); selDupe.style = btnStyle; selDupe.value = "Select Same"; selDupe.id = "selectdupe"; selDupe.classList.add("major"); selDupe.type = "button"; selDupe.addEventListener('mouseup', evt => { let temp = document.querySelectorAll('#messages > tr'); let msgs = []; for (let i = temp.length - 1; i >= 0; i--) { msgs.push(temp[i]); } let titles = []; msgs.forEach((msg) => { let title = msg.querySelector('a.major').textContent; if (/^New update: /.test(title)) { // Select only adventure updates if (titles.indexOf(title) === -1) { if (msg.querySelector('td').style.cssText !== "border-left: 8px solid rgb(221, 221, 221);") { titles.push(title); } } else { msg.querySelector('input').click(); } } }); }); // Add buttons to the page. let del = document.querySelector('#deletemsgs'); del.parentNode.appendChild(document.createElement('br')); del.parentNode.appendChild(selRead); del.parentNode.appendChild(selDupe); } else if (location.pathname === "/my/stories/") { let guides = ["MSPFA Etiquette", "Fanventure Guide for Dummies", "CSS Guide", "HTML and CSS Things"]; let ids = ["27631", "29299", "21099", "23711"]; let authors = ["Radical Dude 42", "nzar", "MadCreativity", "seymour schlong"]; let parentTd = document.querySelector('.container > tbody > tr:last-child > td'); let unofficial = parentTd.querySelector('span'); unofficial.textContent = "Unofficial Guides"; let guideTable = document.createElement('table'); let guideTbody = document.createElement('tbody'); guideTable.style.width = "100%"; guideTable.style.textAlign = "center"; guideTable.appendChild(guideTbody); parentTd.appendChild(guideTable); for (let i = 0; i < guides.length; i++) { let guideTr = guideTbody.insertRow(i); let guideTd = guideTr.insertCell(0); let guideLink = document.createElement('a'); guideLink.href = '/?s='+ids[i]; guideLink.textContent = guides[i]; guideLink.className = "major"; guideTd.appendChild(guideLink); guideTd.appendChild(document.createElement('br')); guideTd.appendChild(document.createTextNode('by '+authors[i])); guideTd.appendChild(document.createElement('br')); guideTd.appendChild(document.createElement('br')); } } else if (location.pathname === "/user/") { let userInterval = setInterval(() => { if (window.MSPFA) { window.MSPFA.request(0, { do: "user", u: location.search.slice(3) }, user => { if (typeof user !== "undefined") { let stats = document.querySelector('#userinfo table'); let joinTr = stats.insertRow(1); let joinTextTd = joinTr.insertCell(0); joinTextTd.appendChild(document.createTextNode("Account created:")); let d = new Date(user.d).toString().split(' ').splice(1, 4).join(' '); let joinDate = joinTr.insertCell(1); let joinTime = document.createElement('b'); joinTime.appendChild(document.createTextNode(d)); joinDate.appendChild(joinTime); } }, status => { console.log(status); }, true); clearInterval(userInterval); } }, 500); } })();