// ==UserScript==
// @name linux.vbird.org 鸟哥的 Linux 私房菜 美化 自动转换简体中文
// @namespace https://greasyfork.org/zh-CN/scripts/389880-linux-vbird-org
// @version 0.4.0
// @description linux.vbird.org 鸟哥的 Linux 私房菜网站 美化:修改字体,增大页面宽度,修改颜色;调用 OpenCC 自动转换成简体中文。转换需要几秒钟,页面可能会没有响应。
// @author Phuker
// @match *://linux.vbird.org/*
// @connect opencc.byvoid.com
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
// - - - - - - - - - - Start User Config - - - - - - - - - -
var option_apply_css = true; // 自动美化外观样式
var option_auto_convert_chinese = true; // 自动把繁体中文转换为简体中文
var option_convert_chinese_on_dbclick = true; // 双击网页时把繁体中文转换为简体中文
// Advanced
var opencc_program = 'wasm'; // Valid: 'wasm' 'api'
var opencc_wasm_base_url = 'https://oyyd.github.io/wasm-opencc/';
var opencc_api_url = 'https://opencc.byvoid.com/convert';
// - - - - - - - - - - End User config - - - - - - - - - -
function remove_original_css_2013(){
var count = 0;
var links = document.getElementsByTagName('link');
for(var i = 0; i < links.length; i++){
var link = links[i];
if(link.getAttribute('href') == "/include/style_2013.css"){
link.remove();
count++;
}
}
return count;
}
function remove_iframes(){
var iframes = document.getElementsByTagName('iframe');
for(var i = 0; i < iframes.length; i++){
var iframe = iframes[i];
if(iframe.getAttribute('src') == "/online/index_2013.php"){
iframe.remove();
}
}
}
function add_opencc_base_tag(url){
var base = document.createElement('base');
base.href = url;
document.body.appendChild(base);
}
function remove_base_tags(){
var tags = document.getElementsByTagName('base');
for(var i = 0; i < tags.length; i++){
tags[i].remove();
}
}
function freeze_page(){
document.body.style['pointerEvents'] = 'none';
}
function de_freeze_page(){
document.body.style['pointerEvents'] = '';
}
function get_title_logger(title){
return (function (txt){
if(txt){
console.log('Set title: ' + txt);
document.title = txt + ' - ' + title;
} else {
console.log('Reset title');
document.title = title;
}
})
}
if(document.location.href.startsWith('http://')){ // Old version website
console.log('Old version website detected');
document.phuker_old_version_website = true;
} else {
console.log('New version website detected');
document.phuker_old_version_website = false;
}
if(document.phuker_old_version_website){
remove_iframes(); // iframe make bugs when convert Chinese
}
if(option_apply_css){
if(document.phuker_old_version_website){
if(remove_original_css_2013()){
GM_addStyle(`
/* 全部的風格一致設定值 ################################################################## */
body {
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
font-size: 12pt;
/*padding: 32px 0 27px 0 ;*/
margin: 0;
background-color: #eeeeee;
color: #000000;
background-attachment:fixed ;
line-height: 1.6;
}
#book1, #book2, #book3, #book4, #book5 {
display: none;
}
/* top iframe*/
iframe{
display: none;
}
pre, legend, blockquote, span {
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
}
a:link {text-decoration: none; color: blue}
a:visited {text-decoration: none; color: blue}
a:active {text-decoration: none; color: blue}
a:hover {text-decoration: underline; color: #ff0000}
/* 最上面那個不會動的方塊設定值 ############################################################ */
.toparea {
width: 100%;
overflow: auto;
/* min-width: 1000px;*/
min-height: 36px;
box-shadow: 2px 2px 2px 2px gray;
/*position: absolute;*/
top: 0;
left: 0;
/* background-color: #1E90FF;*/
/*background-color: rgb(85,123,205);*/
/*background-color: rgba(85,123,205,0.5);*/
background-color: #003366;
color: white;
font-size: 16pt;
font-weight: bold;
text-align: center;
line-height: 1.4;
z-index: 10;
}
.toparea span{
/*text-shadow: 1px 1px 1px black !important;*/
font-weight: 100;
}
.toparea ul {
position: relative;
padding: 0;
margin: 5px 0 0 10px;
display: inline-block;
}
.toparea li {
display: inline-block;
font-size: 9pt;
font-weight: normal;
border-top: 1px solid #191970;
border-left: 1px solid #191970;
border-right: 1px solid #191970;
border-radius: 6px 6px 0 0;
box-shadow: 2px 2px 2px 1px gray;
padding: 5px 5px 0 5px;
margin: -2px;
background-color: #99ccff;
}
.toparea a {
color: #000000;
}
.toparea li:hover {
transition: background-color 1s;
border-top: 1px solid black;
border-left: 1px solid black;
border-right: 1px solid black;
box-shadow: 2px 2px 2px 1px #191970;
background-color: white;
color: black;
padding-top: 10px;
}
.toparea a:hover {
color: darkblue;
}
li.topareali {
border-top: 1px solid black;
border-left: 1px solid black;
border-right: 1px solid black;
box-shadow: none;
background-color: white;
padding-top: 10px;
padding-bottom: 4px;
color: black;
}
.topareali a {
color: darkblue;
font-weight: bold;
}
/* 左邊的往前一頁功能 ############################################################ */
.leftarea {
width: 40px;
height: 30px;
position: fixed;
top: 50%;
left: 0;
bottom: 50%;
background-color: rgba(85,123,205,0.2);
color: white;
font-size: 16pt;
/*text-shadow: 1px 2px 1px gray;*/
font-weight: bold;
text-align: center;
border-radius: 0 10px 0 0 ;
z-index: 10;
}
.leftarea a {
color: white;
text-decoration: none;
display: block;
}
.leftarea a:hover {
color: blue;
text-shadow: 2px 2px 2px black;
background-color: #eeeeee ;
}
/* 右邊的往後一頁功能 ############################################################ */
.rightarea {
width: 40px;
height: 30px;
position: fixed;
top: 50%;
right: 0;
bottom: 50%;
background-color: rgba(85,123,205,0.2);
color: white;
font-size: 16pt;
text-shadow: 2px 2px 2px gray;
font-weight: bold;
text-align: center;
z-index: 10;
border-radius: 10px 0 0 0 ;
}
.rightarea a {
color: white;
text-decoration: none;
display: block;
}
.rightarea a:hover {
color: blue;
text-shadow: 2px 2px 2px black;
background-color: #eeeeee ;
}
/* 最底下那個不會動的版權宣告頁面 ######################################################################## */
.bottomarea {
width: 100%;
/* min-width: 1000px;*/
min-height: 30px;
box-shadow: 0px 0px 2px 2px gray;
/*position: fixed;*/
overflow: auto;
bottom: 0;
left: 0;
/* background-color: #1E90FF; */
background-color: rgb(85,123,205);
color: #AFEEEE;
font-size: 10pt;
font-weight: normal;
text-align: center;
z-index: 10;
}
.bottomarea ul {
position: relative;
padding: 0;
margin: 0;
display: inline-block;
}
.bottomarea li {
display: inline-block;
font-size: 9pt;
font-weight: normal;
border-left: 1px solid #191970;
border-right: 1px solid #191970;
border-bottom: 1px solid #191970;
border-radius: 0 0 6px 6px;
box-shadow: 0px 0px 2px 2px gray;
padding: 0px 5px 0px 5px;
margin: -2px;
background-color: #87CECB;
}
.bottomarea a {
color: #AFEEEE ;
}
.bottomarea li a {
color: #696969;
}
.bottomarea li:hover {
transition: background-color 1s;
border-left: 1px solid black;
border-right: 1px solid black;
border-bottom: 1px solid black;
box-shadow: 0px 0px 2px 1px #191970;
background-color: white;
color: black;
padding-bottom: 5px;
}
.bottomarea a:hover {
color: darkblue;
}
/* 作為兩個板塊置中排版 的必要資料而以~ ######################################################## */
.tablearea {
width: 95%;
min-height: 650px;
padding: 0;
margin: 0 auto 0 6px;
}
/* 左側的那個超連結部分的資料!先針對主選單來設計 ############################################### */
.nav {
width: 142px;
/*height: 540px;*/
float: left;
border: 1px solid gray;
position: absolute;
margin: 10px 0px 10px 0px;
background-color: #ffffff;
box-shadow: 0px 0px 1px 1px gray;
border-radius: 5px ;
z-index:1;
}
/*人数统计*/
.nav p {
display: none;
}
.nav div{
display: none;
}
.nav ul {
position: relative;
padding: 0;
margin-left: 5px;
display: block;
}
.nav li {
display: block;
font-size: 10pt;
font-weight: lighter;
width: 115px;
border-left: 10px solid #ccc;
border-right: 1px solid #fff;
border-bottom: 1px solid #fff;
border-top: 1px solid #fff;
border-radius: 0 5px 0 0;
padding: 3px 0px 0px 5px;
margin: 0px;
background-color: #336699;
}
.nav li a {
color: white;
display: block;
}
.nav li:hover {
transition: background-color 1s;
border-left: 10px solid #ccc;
border-right: 1px solid #fff;
border-bottom: 1px solid #fff;
border-top: 1px solid #fff;
background-color: #003366;
}
.nav li a:hover {
color: white;
text-shadow: 1px 1px 0px black;
}
/* 開始設計子選單囉! */
.nav ul li ul {
visibility: hidden;
min-width: 250px;
width: auto;
height: auto;
position: absolute;
float: left;
border: 1px solid gray;
margin: -20px 0px 0px 100px;
background-color: #f3f3f3;
box-shadow: 5px 5px 3px 3px gray;
padding: 10px 0 10px 10px;
border-radius: 7px ;
z-index:1;
overflow: auto;
opacity: 0.95;
}
.nav ul li ul li {
overflow: hidden;
width: 220px;
height: 0;
transition: height 0.2s ease-in, visibility 0.2s;
}
.nav ul li:hover ul li {
height: 20px;
}
.nav ul li:hover ul {
visibility: visible;
}
.nav ul ul li:hover {
display: block;
border-left: 10px solid #4b0082;
background-color: gray;
}
li.nav_more {
background-color: #003366;
border-color: #fff;
border-left-color: #ccc;
}
/* 開始設計主要的教學頁面部分。這就是主要出現的咚咚! ####################################3 */
.mainarea {
width: 75%;
margin: 0 auto;
padding: 0 0 0 160px;
text-align: left;
line-height: 1.6;
position: relative;
/* float: right;*/
color: #252525;
}
.block1 {
padding: 0 20px 10px 40px;
/* text-align: justify; */
text-align: left;
background-color: white;
border: 1px solid gray;
border-radius: 5px;
box-shadow: 1px 1px 1px gray;
margin-top: 10px;
position: relative;
}
.block1 h1 {
font-size:18pt;
font-weight: lighter;
text-align: center;
color: white;
background-color: #003366;
margin: 5px -10px 2px -35px;
padding: 5px;
border: 1px solid gray;
box-shadow: 1px 1px 1px 0px gray;
border-radius: 8px 8px 0 0 ;
}
.block1 h2 {
font-size:16pt;
text-align: left;
color: #333333 ;
background-color: #99CCFF;
margin: 5px 0px 15px -30px;
padding: 5px 5px 0px 10px;
border: 1px solid gray;
box-shadow: 2px 2px 2px 0px gray;
border-radius: 0px 10px 0 0 ;
}
.abstract {
background-color: #ffffcc;
border: 1px solid #ffffcc;
padding: 10px 10px 0 10px;
font-size: 10pt;
color: #000099;
text-align: justify;
border-radius: 5px;
box-shadow: 0 0 1px 1px gray;
margin-left: -20px;
}
.abstract p {
margin-top: 0px;
}
.links {
color: #0000BB;
margin-left: -50px;
}
.links ul {
list-style-type: none;
font-size: 15pt;
color: #0000BB;
font-weight: normal;
}
.links ul ul {
font-size: 13pt;
display: block;
}
.links a:visited {
color: #666666;
}
.block2 {
padding: 0px 5px 5px 20px;
/* text-align: justify; */
text-align: left;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
position: relative;
}
.block2 h2 {
font-size:14pt;
text-align: left;
color: #333333 ;
background-color: #99CCFF;
margin: -1px 0px 10px -21px;
padding: 5px 5px 0px 10px;
border: 1px solid gray;
box-shadow: 0px 1px 1px 0px gray;
border-radius: 0px 0px 0 0 ;
}
.gototop {
display: block;
width: 30px;
background-color: #E6E6FA;
font-weight: bold;
position: absolute;
left: 0px;
bottom: 0px;
padding: 2px;
border: 1px solid gray;
margin: 2px;
z-index: 0;
}
.gototop a {
display: block;
}
ul.toplist {
margin-left:0;
padding-left:0;
color:#000088;
font-weight: bold;
list-style-type: square;
border-top: 1px solid gray;
margin-top: 30px;
}
table.exam {
width: 95%;
border: 1px solid black;
border-collapse: collapse;
padding: 5px;
}
table.exam td {
padding: 5px;
}
table.exam td div {
margin: 10px 0 10px 25px;
width: 95%;
}
table.news {
width: 97%;
border: 1px solid gray;
background-color: #FFFFCC;
box-shadow: 2px 2px 2px 2px gray;
padding: 0px;
margin: 0;
border-collapse:collapse;
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
}
table.news tr {
margin: 0;
padding: 0;
border-width: 0;
}
table.news tr.title1 {
background-color: lightblue;
text-align:center;
border-width: 0;
}
table.news td {
margin: 5px;
padding: 5px;
border: 1px solid gray;
}
table.news tr:hover {
/* text-shadow: 1px 1px 1px black;*/
background-color: lightblue;
color: black;
}
table.news .theader {
background-color: lightblue;
text-align: center;
}
table.news .tcenter {
text-align: center;
}
.text_import1 {
color: #000088;
font-weight: bold;
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
}
.text_import2 {
color: #000088;
font-weight: normal;
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
}
.text_vbird {
color: #000088;
font-weight: normal;
font-style: italic;
}
.text_history {
font-size: 10pt;
color: #000066;
}
.text_date {
font-size: 10pt;
color: #3333FF;
}
table.term {
width: 650px;
background-color: #000000;
border-style: ridge;
border-width:3px;
border-color: #FFCCCC;
margin:10px 0px;
}
table.term td {
font-size: 10pt;
color: #FFFFFF;
}
table.term td pre {
font-size: 10pt;
color: #FFFFFF;
margin-top: 2px; margin-bottom: 2px;
}
.term_hd {
font-size: 10pt;
color: #BBBBBB;
}
.term_note {
font-size: 10pt;
color: #777777;
font-weight: normal;
}
.term_note_b {
font-size: 10pt;
color: #FF77FF;
font-weight: bolder;
}
.term_command {
font-size: 10pt;
color: yellow ;
font-weight: bolder;
}
.term_write {
font-size: 10pt;
color: yellow ;
font-weight: normal;
}
.term_say {
font-size: 10pt;
color: #FF6666;
font-weight: normal;
}
.term_white {
font-size: 10pt;
color: #000000;
background-color: #FFFFFF;
}
.vbirdface {
text-align: left;
position: relative;
width: 80%;
margin-left: 12%;
font-size: 10pt;
color: #009000;
border-right: none;
border-bottom: none;
}
.illus {
padding-left: 25px;
}
.illus > ul {
list-style-type: circle;
margin-left: 9px;
margin-bottom: 0px;
padding: 0;
}
.illus > ul > li {
color: #000088;
font-weight: normal;
}
.illus ol {
margin-left: 9px;
margin-bottom: 0px;
padding: 0;
}
.illus p {
margin: 10px;
}
ul.mylist li, ol.mylist li {
margin-top: 10px;
}
/*
3. CSS 語法的 Style 風格:
text_import1 內文部分的特重要文字!
text_import2 內文部分的普通重要文字!
text_vbird 鳥哥的額外說明部分文字
text_history 網頁中,變動的歷史紀錄的日期文字
text_date
block1 大標題下的文字敘述之縮排
block2 小標題下的文字敘述之縮排
vbirdface1 鳥哥的說明最上方的一些標示
vbirdface2 說明的下方標籤在 vbirdface1, 2 之間,插入我所想要講的話!
*/
table.term2 {width: 350px; background-color: #000000;
border-style:groove;border-width:3px;border-color: #FFCCCC; margin:10px 0px;}
*.list1 {list-style-type: square ; padding-left:0; margin-bottom:0 }
*.listol { padding-left:0; margin-bottom:0 }
*.blockex {
padding: 10px 0px 10px 25px ;
font-size: 9pt;
color: #FFFFFF ;
text-align: left ;
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
}
.blockex span {
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
}
*.fontwidth { }
*.fontwidth td { text-align: justify; }
.ex {
width: 95%;
border: 1px solid black;
box-shadow: 0 0 2px 2px silver;
padding: 10px;
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
line-height: 120%;
background-color: rgba(200,200,200,0.7);
}
.ex .list li {
margin-top: 10px;
}
@media (max-width: 850px){
.toparea span{
display: none !important;
}
.nav {
display: none !important;
}
.mainarea{
width: 100% !important;
margin: 0 !important;
padding: 0 !important;
}
}
`);
}
} else {
GM_addStyle(`
* {
font-family: 'Consolas', 'Monaco', 'Microsoft Yahei','PingFang SC', Monospace !important;
}
`);
}
}
// 使用 wasm-opencc 在浏览器中转换,地域用词可能不太准确
// https://github.com/oyyd/wasm-opencc
// https://oyyd.github.io/wasm-opencc/
function convert_chinese_wasm (){
var original_title = document.title;
var title_log = get_title_logger(original_title);
if(document.phuker_convert_chinese_started){
console.log('Convert already started');
return;
} else {
console.log('Start convert');
document.phuker_convert_chinese_started = true;
}
freeze_page(); // Limit <base> tag
add_opencc_base_tag(opencc_wasm_base_url);
title_log('正在加载 OpenCC');
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = './opencc-asm.js';
script.onload = function(){
try{
const { DictSource, Converter } = OpenCCWasm_
OpenCCWasm_.ready().then(() => {
const dictSource = new DictSource('tw2sp.json');
return dictSource.get();
}).then((args) => {
title_log('已加载 OpenCC');
const converter = new Converter(...args);
var body_html = document.body.innerHTML;
title_log('正在转换为简体中文');
body_html = converter.convert(body_html);
title_log('转换完毕');
document.body.innerHTML = body_html;
remove_base_tags();
de_freeze_page();
title_log = get_title_logger(converter.convert(original_title));
title_log('');
converter.delete();
})
} catch (e) {
title_log('OpenCC 错误');
remove_base_tags();
de_freeze_page();
}
}
script.onerror = function(){
title_log('加载 OpenCC 失败');
remove_base_tags();
de_freeze_page();
}
window.addEventListener('error', function(e){
title_log('脚本错误');
console.log(e);
remove_base_tags();
de_freeze_page();
})
document.body.appendChild(script);
}
// 通过 BYVoid 大神的在线工具转换,地域用词更准确
// https://opencc.byvoid.com/
function convert_chinese_api(){
var original_title = document.title;
var title_log = get_title_logger(original_title);
if(document.phuker_convert_chinese_started){
console.log('Convert already started');
return;
} else {
console.log('Start convert');
document.phuker_convert_chinese_started = true;
}
function call_api(text, onload, onerror){
GM_xmlhttpRequest({
method: 'POST',
url: opencc_api_url,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: 'text=' + encodeURIComponent(text) + '&config=tw2sp.json&precise=0',
onload: onload,
onerror: onerror,
ontimeout: onerror
});
}
title_log('正在转换为简体中文');
call_api(document.body.innerHTML, function(resp){
var result = resp.responseText;
title_log('转换完毕');
document.body.innerHTML = result;
title_log('');
}, function(){
title_log('转换失败')
});
}
var convert_chinese = convert_chinese_wasm; // default
if(opencc_program == 'api'){
convert_chinese = convert_chinese_api;
}
if(option_auto_convert_chinese){
window.addEventListener('load', convert_chinese);
}
if(option_convert_chinese_on_dbclick){
window.addEventListener('load', function(){
document.addEventListener('dblclick', convert_chinese);
})
}
})();