// ==UserScript==
// @name txt阅读器(仿pixiv,多主题)
// @namespace http://tampermonkey.net/
// @version 2.0.1
// @description 访问txt时,美化阅读样式,有多个主题可供切换
// @author Yesaye
// @match *://*/*.txt
// @match file:///*/*.txt
// @grant GM_setValue
// @grant GM_getValue
// @license MIT
// @icon data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIAIAAgAMBIgACEQEDEQH/xAAbAAADAQEBAQEAAAAAAAAAAAAABwgGBQMEAv/EAEsQAAAEBAAGDQcJBgcAAAAAAAABAgMEBQYRBwgSITZRExcxNUFVYXN0k7Gy0xZWdYGUs9EUGCIyYnFykdI3OEJSVJUVIzNDU6Hw/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AHiAAAAPKLiGoSFeiYhWSyy2pxatSSK5n+Q9RnsIilIoSoDSZkf+HvFcvwGARcZOawws1E/ByZxxiAbupDJOG2203exG4ZfWUfr4bFYfTtC1PxjJ+td8MaLFoSkoCfKsWUbrJGfIRL+Jh1AJz2hKn4xk/Wu+GDaEqfjGT9a74YowACc9oSp+MZP1rvhg2hKn4xk/Wu+GKMAAlKt8Gc4ouVszCZxUA806+TCUw61molGlSr50lm+iY+vBnhBj6KjWoeYk+7JYoiUppV/oFcy2Ru/KR3Isx2PhIMvGP0LgPSSPduD5qdoeBrXA9JWHslmOZbdOFirZ0Hsq8x60nwl6wDZgYyGmEGzGQLyH4Z5JLbcQdyURj3E20NV82wZVA9T9SNOlLtks60ec2TP/AHEa0numRbu7u7tGwkSxGQzUTCOoeYdSS23EHdKiPcMjAeoAAAAAAAAzmEbQKoOgPd0xoxnMI2gVQdAe7pgFzi073T3nmexQdIS2LTvdPeeZ7FB0gAAAAAAAAFRjH6FwHpJHu3Bo8DX7NJJ+Bz3qxnMY/QuA9JI924NHga/ZpJPwOe9WA/eEig4KtZXknksTNhJ/Jom259lWtJ/9bpajUWDytpjg7nbtN1Q26iXk7krQrOcKo/4060Hunb7y5aOGIwm4P4StJdltZDE2YSfyeIMsyi/kX9ns3dZGGzYeaiWG34dxDrTiSUhaDulRHuGR6h6CdsGleR1DTZymKrS63ApdNH+ZnVCL1lrQe7m13LlodtxDraHGlpW2siUlSTuSiPcMjAfoA5dSVBLaZlTkym7+xQ6DySsV1LUe4lJcJmFc9jAS0nDJiQxa2+BS30pP8iI+0A5RnMI2gVQdAe7phc/OBgvN6I9qT+kc2psNsJOqemMrRI32lRcOtknDiCMk5RWvbJAdLFp3unvPM9ig6RL2C7CKxQ0NMGXpa5GHFrQojQ6SMnJIy1HrG4+cDBeb0R7Un9IB0gCW+cDBeb0R7Un9IPnAwXm9Ee1J/SAdIAlvnAwXm9Ee1J/SP03jAS81kTsgiko4TTEJMy9ViAd3D5KY+bUYwmWwrsSuHjkOuIZQalEjIWm9i5VEFdIKywg0/KIeVS6XPphYcjJsly5SjzqNR57azMUBSVUyurZWUfKHjUgjyXG1lZbStSi+GYdsBOm2XhN/oHP7Yr4A2y8Jv9A5/bFfAUWABJVXx9U1S83GTqTuk8wgyN9uAU2Zp3bKO2ci5dzOGfi5z6OjIOZSeKdU7DQRNrhso7m2SjVdP3ZiMtWcNSpdHJr0N7uGEvi074z3mWe1QD1xl4lzZpDC5Vmsl5wy1qukv/feY3tKUBSiKblhuyOCfdXCtrcdfaJalqNJGZmZ8oXuMtvjIuZe7Uh0U1o5Kuhs9wgHO8g6S825X7Mn4A8g6S825X7Mn4DiYQMIz1HzZiAakD8xJ2HJ7ZW3jQSbqUWTbIP+W/rGTTh7Wp42U0m8bpbqCjPpF6tjAMfyDpLzblfsyfgDyDpLzblfsyfgM3I8JkfOZBOZoxSzyHJWltZwy4kyU8lWVlGk9j3Ukm9rZ+3sYOa9g65gYh1mHOEioZdnYZTmWZJP6qiOxXI8/BwAPs8g6S825X7Mn4A8g6S825X7Mn4DPQ2FBMyrpVMSSTnGpQ6aHI35TkoSSfrqtknmLOW7nzaxx5xhoiJZM46EOk4lxEK+41s3ykyJRJUZZX+nmLNcBufIOkvNuV+zJ+A8Y3B3SMXCuw5yCAa2RJpy2WSQtPKRluGF+zh5cfI1MUi+4RZjNEYZ2/JsNSlpwqfyCCmq4RUIqJQajYUrKNGcytexatQBG4t0S4mqZnCko9icgNkUnWpLiSLvGKHE54uGmkf6NX7xsUYAAAAA5tS6OTXob3cMJfFp3xnvMs9qg6Kl0cmvQ3u4YS+LTvjPeZZ7VADGW3xkXMvdqQ6Ka0clXQ2e4QS+MtvjIuZe7Uh0U1o5Kuhs9wgHSCGpP94aac7E90PkIak/3hppzsT3QD53RNGEWEiMHFcRLtNRhQ7UxhlqJps87SV3JSbcBEZXSfBYtQoOpp7B03I4qbR6rMw6LkkjzrVwJLlM8wRFE0lF4UptOahqF1xuHXlIaWn/AJTL6JJ+ygrZuHNygGBgLpWHk1LNzhSm3Y2aJJZuJO+xt/woI9fCfLm4Bsq00Onvo6I92oKDBBUUXSNTRVD1EexoU+aWDUeZt7UR/wAqysZcttYb9aaHT30dEe7UAXGLZo5NumF3CDgCfxbNHJt0wu4QcACc8XDTSP8ARq/eNijBOeLhppH+jV+8bFGAAAAAObUujk16G93DCXxad8Z7zLPaoOipdHJr0N7uGEvi074z3mWe1QAxlt8ZFzL3akOimtHJV0NnuEMDh1o6OqSUwcfKGVPxUvNeWwgvpONqte2syNO5ymFzLMMlWSKXw8rdgoBw4VtLSVRTDhOZJFYr2UXAWoBSw5jFPyeHmi5qxLIVuYLMzVEpaInFGe7dW7nCG2+6n4uk/VO+IDb7qfi6T9U74gB/zaUS6csJh5tBMRjKFZaW30EpJKta9j4c5j0l8BByyERCS6GahoZu+Q0ygkpTc7nYi5TE+bfdT8XSfqnfEBt91PxdJ+qd8QA9pjTMimkYUZMZRBRMURERPOspUuxbmcdKIYaiWHIeIbS4y6g0OIWVyUkysZGWqwnfb7qfi6T9U74gNvup+LpP1TviAH7KZNLJK0tqUwEPBtuKylpYbJBKPWdh94nPb7qfi6T9U74g84jDhVscwuFh4KWtOupNKVsMuGtN+FN1nn9QD0xcNNI/0av3jYowJ/AHRkwkyIyeTaHXDORTZMw7LibLyLko1GXBcyTYj1fcHAAAAAA5tS6OTXob3cMJfFp3xnvMs9qg6Kl0cmvQ3u4YS+LTvjPeZZ7VAH0AAAAM5hG0CqDoD3dMaMZzCNoFUHQHu6YBc4tO90955nsUHSEti073T3nmexQdIAAAAAAAAAAAAAAAADm1Lo5Nehvdwwl8WnfGe8yz2qDoqXRya9De7hhL4tO+M95lntUAfQAAAAz2ERKl0JUBJIzP/D3jsX4DGhHlFw7UZCvQsQnKZebU2tOtJlYy/IAmsWhSTgJ8m5ZROsmZcll/Aw6hNUXJ6wwT1E/Fydpx+AculDxNG4063e5E4RfVUXq4bHYfTt9VPxdJ+qd8QBRgBOe33U/F0n6p3xAbfdT8XSfqnfEAUYATnt91PxdJ+qd8QG33U/F0n6p3xAFGAE57fdT8XSfqnfEBt91PxdJ+qd8QBRgBOe33U/F0n6p3xAbfdT8XSfqnfEAPmp1EimpspRkSSgnjMz4PoGEzi0JUcfPl2PJJpkjPlM1/AxwJrhDrevYNUmgoBBNRBkh1Evh13WWpSjM7Fr3OXMHBglopdG0+tEaaTmMYsnInJO5ItmSgj4bEZ59ZmA//2Q==
// ==/UserScript==
(function () {
'use strict';
// 主题定义
const themes = {
light: {
name: '明亮',
background: '#f5f5f5',
containerBg: '#ffffff',
textColor: '#1f1f1f',
btnBg: '#ffffff',
btnColor: '#23272e',
btnBorder: '#cccccc'
},
classic: {
name: '经典',
background: '#fafafa',
containerBg: '#f0f0f0',
textColor: '#222',
btnBg: '#e0e0e0',
btnColor: '#222',
btnBorder: '#bdbdbd'
},
paper: {
name: '纸张',
background: '#fdf6e3',
containerBg: '#ffffff',
textColor: '#333333',
btnBg: '#f5f2e7',
btnColor: '#333333',
btnBorder: '#e0e0e0'
},
sepia: {
name: '羊皮纸',
background: '#f4ecd8',
containerBg: '#f9f6f2',
textColor: '#5b4636',
btnBg: '#e9e1c8',
btnColor: '#5b4636',
btnBorder: '#d6cfc2'
},
gray: {
name: '灰色',
background: '#e0e0e0',
containerBg: '#f5f5f5',
textColor: '#424242',
btnBg: '#bdbdbd',
btnColor: '#212121',
btnBorder: '#9e9e9e'
},
bluegray: {
name: '蓝灰',
background: '#eceff1',
containerBg: '#cfd8dc',
textColor: '#263238',
btnBg: '#b0bec5',
btnColor: '#263238',
btnBorder: '#78909c'
},
// 暗色风格
dark: {
name: '暗黑',
background: '#23272e',
containerBg: '#181a1b',
textColor: '#e0e0e0',
btnBg: '#23272e',
btnColor: '#e0e0e0',
btnBorder: '#444'
},
nightblue: {
name: '夜蓝',
background: '#1a2233',
containerBg: '#222c3a',
textColor: '#b3c7e6',
btnBg: '#2a3550',
btnColor: '#b3c7e6',
btnBorder: '#3b4a6b'
},
nord: {
name: '北极',
background: '#2e3440',
containerBg: '#3b4252',
textColor: '#d8dee9',
btnBg: '#4c566a',
btnColor: '#eceff4',
btnBorder: '#81a1c1'
},
monokai: {
name: '莫诺凯',
background: '#272822',
containerBg: '#383830',
textColor: '#f8f8f2',
btnBg: '#49483e',
btnColor: '#a6e22e',
btnBorder: '#fd971f'
},
dracula: {
name: '德古拉',
background: '#282a36',
containerBg: '#44475a',
textColor: '#f8f8f2',
btnBg: '#6272a4',
btnColor: '#f1fa8c',
btnBorder: '#bd93f9'
},
solarized: {
name: '日光',
background: '#fdf6e3',
containerBg: '#eee8d5',
textColor: '#657b83',
btnBg: '#eee8d5',
btnColor: '#586e75',
btnBorder: '#93a1a1'
},
// 彩色/特殊风格
pink: {
name: '粉色',
background: '#ffe4ec',
containerBg: '#fff0f6',
textColor: '#ad1457',
btnBg: '#f8bbd0',
btnColor: '#ad1457',
btnBorder: '#f06292'
},
ocean: {
name: '海洋',
background: '#e0f7fa',
containerBg: '#b2ebf2',
textColor: '#006064',
btnBg: '#4dd0e1',
btnColor: '#006064',
btnBorder: '#00bcd4'
},
coffee: {
name: '咖啡',
background: '#ece0d1',
containerBg: '#d7ccc8',
textColor: '#4e342e',
btnBg: '#bcaaa4',
btnColor: '#4e342e',
btnBorder: '#8d6e63'
},
green: {
name: '绿色',
background: '#e8f5e9',
containerBg: '#c8e6c9',
textColor: '#1b5e20',
btnBg: '#a5d6a7',
btnColor: '#1b5e20',
btnBorder: '#81c784'
},
forest: {
name: '森林',
background: '#e8f5e9',
containerBg: '#a5d6a7',
textColor: '#2e7d32',
btnBg: '#66bb6a',
btnColor: '#1b5e20',
btnBorder: '#388e3c'
},
sunset: {
name: '落日',
background: '#fff3e0',
containerBg: '#ffe0b2',
textColor: '#e65100',
btnBg: '#ffb74d',
btnColor: '#e65100',
btnBorder: '#ff9800'
},
lavender: {
name: '薰衣草',
background: '#f3e8ff',
containerBg: '#e1bee7',
textColor: '#6a1b9a',
btnBg: '#ce93d8',
btnColor: '#6a1b9a',
btnBorder: '#ab47bc'
}
};
// 读取主题(优先GM_getValue,其次localStorage)
let currentTheme = 'light';
let canUseLocalStorage = true;
try {
// 测试localStorage可用性
localStorage.getItem('txt_reader_theme');
} catch (e) {
console.log(e);
canUseLocalStorage = false;
}
if (typeof GM_getValue === 'function') {
try {
currentTheme = GM_getValue('txt_reader_theme', canUseLocalStorage ? localStorage.getItem('txt_reader_theme') || 'light' : 'light');
console.log("GM_getValue: "+currentTheme);
} catch (e) {
console.log(e);
currentTheme = 'light';
}
} else if (canUseLocalStorage) {
try {
currentTheme = localStorage.getItem('txt_reader_theme') || 'light';
console.log("localStorage: "+currentTheme);
} catch (e) {
console.log(e);
currentTheme = 'light';
}
} else {
currentTheme = 'light';
}
// 创建主题下拉框
const themeSelect = document.createElement('select');
themeSelect.style.position = 'fixed';
themeSelect.style.top = '20px';
themeSelect.style.right = '20px';
themeSelect.style.zIndex = 9999;
themeSelect.style.borderRadius = '6px';
themeSelect.style.padding = '8px 16px';
themeSelect.style.boxShadow = '0 2px 8px 0 rgba(0,0,0,0.04)';
themeSelect.style.cursor = 'pointer';
themeSelect.style.transition = 'all 0.2s';
// 填充下拉框选项
const themeKeys = Object.keys(themes);
themeKeys.forEach(key => {
const option = document.createElement('option');
option.value = key;
option.textContent = themes[key].name || key;
themeSelect.appendChild(option);
});
themeSelect.value = currentTheme;
document.body.appendChild(themeSelect);
// 创建容器
var text_containter = document.createElement("div");
text_containter.id = "text_containter";
var text_box = document.createElement("div");
text_box.id = "text_box";
text_containter.appendChild(text_box);
document.body.appendChild(text_containter);
// 将原始文本放入 text_box
var pre = document.getElementsByTagName("pre")[0];
if (pre) {
text_box.textContent = pre.textContent;
pre.remove();
}
// 注入自定义样式
var style = document.createElement('style');
style.type = "text/css";
document.head.appendChild(style);
function applyTheme(themeName) {
const theme = themes[themeName];
style.textContent = `
html { background-color: ${theme.background}; }
body {
margin: 0;
padding: 0;
}
#text_containter {
margin: 30px auto;
padding: 60px 0;
width: 912px;
background-color: ${theme.containerBg};
}
#text_box {
color: ${theme.textColor};
max-width: 620px;
margin: auto;
font-size: 16px;
line-height: 2;
background-color: ${theme.containerBg};
font-family: "Avenir Next", Avenir, "Source Sans", "Noto Sans", Roboto, Verdana, "Pingfang SC", "Hiragino Sans GB", "Lantinghei SC", "Source Han Sans CN", "Noto Sans CJK SC", "Microsoft Yahei", DengXian, YuGothic, "Hiragino Kaku Gothic Pro", Meiryo, "Source Han Sans", "Source Han Sans JP", "Noto Sans CJK JP", "Pingfang TC", "Pingfang HK", "Hiragino Sans CNS", "Lantinghei TC", "Source Han Sans TW", "Source Han Sans HK", "Noto Sans CJK TC", "Microsoft JhengHei", "Apple SD Gothic Neo", "Source Han Sans K", "Source Han Sans KR", "Noto Sans CJK KR", "Malgun Gothic", sans-serif;
font-feature-settings: normal;
overflow-wrap: break-word;
white-space: pre-wrap;
text-align: justify;
}
`;
// 下拉框样式跟随主题
themeSelect.style.background = theme.btnBg;
themeSelect.style.color = theme.btnColor;
themeSelect.style.border = `1px solid ${theme.btnBorder}`;
}
// 初始主题
applyTheme(currentTheme);
// 切换主题事件
themeSelect.onchange = function () {
currentTheme = themeSelect.value;
if (canUseLocalStorage) {
try {
localStorage.setItem('txt_reader_theme', currentTheme);
console.log("localStorage saved: "+currentTheme);
} catch (e) { console.log(e); }
} else {
console.log("localStorage not available");
}
if (typeof GM_setValue === 'function') {
try {
GM_setValue('txt_reader_theme', currentTheme);
console.log("GM_setValue saved: "+currentTheme);
} catch (e) { console.log(e); }
} else {
console.log("GM_setValue not available");
}
applyTheme(currentTheme);
};
})();