// ==UserScript==
// @name Font Substitution
// @name:ja フォントを変更します
// @name:ko 글꼴 변경하기
// @name:zh-CN 改变字体
// @name:zh-TW 改變字體
// @namespace https://greasyfork.org/en/scripts/462060-font-substitution
// @version 1.8.4
// @author AeamaN
// @description Substitutes arbitrary fonts on webpages.
// @description:ja ページ内で指定されている、任意のフォントを変更します。
// @description:ko 페이지 내에서 지정된 임의의 글꼴을 변경합니다.
// @description:zh-CN 改变页面中指定的任何字体。
// @description:zh-TW 改變頁面中指定的任何字體。
// @contributionURL bitcoin:1DC6uWJWzzwU3iRJDXhUquv6QAYaRvtfFJ
// @match *://*/*
// @match file:///*
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @run-at document-idle
// ==/UserScript==
// It's based on the original FontSub by Arithon Kelis.
// Arithon Kelis の FontSub を、参考にしています。
(function () { /* START */
'use strict';
// //////////// Settings //////////// //
// No GUI Settings
// Default values are used
var NO_GUI = false;
// ////////////////////////////////// //
// ///////// Default valuse ///////// //
// Array of fonts you want to substitute
// Empty values are ignored
var ORIG_FONTS = [
'Courier(?=,|$)', // 1
'MS Pゴシック', // 2
'MS PGothic', // 3
'MS ゴシック', // 4
'MS Gothic', // 5
'MS UI Gothic', // 6
'MS P明朝', // 7
'MS PMincho', // 8
'MS 明朝', // 9
'MS Mincho', // 10
'', // 11
'' // 12
];
// Array of fonts to replace the org fonts sequentially
// To disable it, specify a non-existent font name
var REPLD_FONTS = [
'Courier New', // 1
'Sarasa Gothic J', // 2
'Sarasa Gothic J', // 3
'Sarasa Fixed J', // 4
'Sarasa Fixed J', // 5
'Sarasa UI J', // 6
'Source Han Serif Medium', // 7
'Source Han Serif Medium', // 8
'HanaMinA Regular', // 9
'HanaMinA Regular', // 10
'', // 11
'' // 12
];
// Modify fonts weight
// -300 -300
// -200 -200
// -100 -100
// 0 0
// 100 +100
// 200 +200
// 300 +300
// 400 +400
// 500 +500
// 9999 Do Nothing
var MOD_FW = 9999;
// Loop interval(ms)
var INTL = 800;
// ////////////////////////////////// //
var ROOT_E = document.documentElement;
var MYNAME = 'fsub184';
var muts = true;
var observer = new MutationObserver(function (mutations) {
muts = mutations;
});
var orig_fonts = [];
var repld_fonts = [];
var mod_fw, intl;
function makeDalg() {
var dalg = document.createElement('div');
dalg.className = 'us-' + MYNAME;
dalg.style.all = 'initial';
dalg.style.backgroundColor = 'rgb(235, 235, 235)';
dalg.style.border = '3px outset';
dalg.style.borderRadius = '1%';
dalg.style.display = 'none';
dalg.style.fontFamily = 'monospace';
dalg.style.fontSize = '12px';
dalg.style.height = '420px';
dalg.style.width = '480px';
dalg.style.paddingLeft = '2px';
dalg.style.paddingRight = '2px';
dalg.style.position = 'fixed';
dalg.style.right = '8px';
dalg.style.top = '8px';
dalg.style.zIndex = '2147483647';
var HTML =
'<span style="all: initial; font-size: 120%; line-height: 210%">' +
GM_info.script.name + ' ' + GM_info.script.version + ' ' + 'Settings' +
'</span><br />\n' +
'01.<input type="text" name="orig0" class="top_tf" />' +
'<span class="top_tf">-></span><input type="text" name="repld0" class="top_tf" /><br />\n' +
'02.<input type="text" name="orig1" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld1" class="mid_tf" /><br />\n' +
'03.<input type="text" name="orig2" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld2" class="mid_tf" /><br />\n' +
'04.<input type="text" name="orig3" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld3" class="mid_tf" /><br />\n' +
'05.<input type="text" name="orig4" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld4" class="mid_tf" /><br />\n' +
'06.<input type="text" name="orig5" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld5" class="mid_tf" /><br />\n' +
'07.<input type="text" name="orig6" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld6" class="mid_tf" /><br />\n' +
'08.<input type="text" name="orig7" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld7" class="mid_tf" /><br />\n' +
'09.<input type="text" name="orig8" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld8" class="mid_tf" /><br />\n' +
'10.<input type="text" name="orig9" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld9" class="mid_tf" /><br />\n' +
'11.<input type="text" name="orig10" class="mid_tf" />' +
'<span class="mid_tf">-></span><input type="text" name="repld10" class="mid_tf" /><br />\n' +
'12.<input type="text" name="orig11" class="btm_tf" />' +
'<span class="btm_tf">-></span><input type="text" name="repld11" class="btm_tf" /><br />\n' +
'<table class="top_t">\n' +
'<tr class="top_tr">\n' +
'<td class="top_td"></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="-300" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="-200" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="-100" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="0" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="100" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="200" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="300" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="400" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="500" class="top_r" /></td>\n' +
'<td class="top_td"><input type="radio" name="mod_fw" value="9999" class="top_r" /></td>\n' +
'</tr>\n' +
'<tr class="btm_tr">\n' +
'<td style="all: initial; font-size: 80%">Weight </td>\n' +
'<td class="btm_td">-3</td>\n' +
'<td class="btm_td">-2</td>\n' +
'<td class="btm_td">-1</td>\n' +
'<td class="btm_td"> 0</td>\n' +
'<td class="btm_td">+1</td>\n' +
'<td class="btm_td">+2</td>\n' +
'<td class="btm_td">+3</td>\n' +
'<td class="btm_td">+4</td>\n' +
'<td class="btm_td">+5</td>\n' +
'<td class="btm_td">DN</td>\n' +
'</tr>\n' +
'</table>\n' +
'<span style="all: initial; font-size: 100%">' +
'Loop interval(ms)* ' +
'</span><input type="text" name="intl" size="10" class="top_ti" />' +
'<span style="all: initial; font-size: 100%">' +
' *Restart required' +
'</span><br />\n' +
'<input type="button" class="top_b" value="Cancel" />\n' +
'<input type="button" class="top_b" value="Set default" />\n' +
'<input type="button" class="top_b" value="Save & Close" />\n';
dalg.innerHTML = HTML;
for (var e of dalg.querySelectorAll(
'input.top_tf, input.mid_tf, input.btm_tf, input.top_ti'
)) {
e.style.all = 'initial';
e.style.backgroundColor = 'rgb(255, 255, 255)';
e.style.fontFamily = 'monospace';
e.style.fontSize = '100%';
e.style.marginLeft = '1px';
e.style.marginRight = '1px';
e.style.marginTop = '1px';
e.style.marginBottom = '0px';
e.style.paddingLeft = '1px';
e.style.paddingRight = '1px';
e.style.paddingTop = '1px';
e.style.paddingBottom = '1px';
}
for (var e of dalg.querySelectorAll('input.top_tf, input.mid_tf, input.btm_tf')) {
e.setAttribute('size', '26');
}
for (var e of dalg.querySelectorAll('span.top_tf, span.mid_tf, span.btm_tf')) {
e.style.all = 'initial';
e.style.fontFamily = 'monospace';
e.style.fontSize = '100%';
e.style.marginLeft = '1px';
e.style.marginRight = '1px';
e.style.marginTop = '1px';
e.style.marginBottom = '0px';
}
for (var e of dalg.querySelectorAll('table.top_t')) {
e.style.all = 'initial';
e.style.display = 'table';
e.style.marginTop = '8px';
e.style.marginBottom = '8px';
}
for (var e of dalg.querySelectorAll('tr.top_tr, tr.btm_tr')) {
e.style.all = 'initial';
e.style.display = 'table-row';
}
for (var e of dalg.querySelectorAll('td.top_td')) {
e.style.all = 'initial';
e.style.display = 'table-cell';
e.style.marginLeft = '0';
e.style.marginRight = '0';
e.style.marginTop = '0';
e.style.marginBottom = '0';
e.style.paddingLeft = '8px';
e.style.paddingRight = '0';
e.style.paddingTop = '0';
e.style.paddingBottom = '0';
}
for (var e of dalg.querySelectorAll('input.top_r')) {
e.style.all = 'initial';
e.style.appearance = 'auto';
e.style.marginLeft = '0';
e.style.marginRight = '0';
e.style.marginTop = '0';
e.style.marginBottom = '0';
e.style.paddingLeft = '0';
e.style.paddingRight = '0';
e.style.paddingTop = '0';
e.style.paddingBottom = '0';
}
for (var e of dalg.querySelectorAll('td.btm_td')) {
e.style.all = 'initial';
e.style.display = 'table-cell';
e.style.fontFamily = 'monospace';
e.style.fontSize = '85%';
e.style.marginLeft = '0';
e.style.marginRight = '0';
e.style.marginTop = '0';
e.style.marginBottom = '0';
e.style.paddingLeft = '8px';
e.style.paddingRight = '0';
e.style.paddingTop = '0';
e.style.paddingBottom = '0';
e.style.textAlign = 'center';
}
for (var e of dalg.querySelectorAll('input.top_b')) {
e.style.all = 'initial';
e.style.backgroundColor = 'rgb(190, 190, 190)';
e.style.borderRadius = '10%';
e.style.cursor = 'default';
e.style.fontSize = '110%';
e.style.marginTop = '10px';
e.style.marginBottom = '0px';
e.style.paddingTop = '6px';
e.style.paddingBottom = '6px';
e.style.textAlign = 'center';
e.style.width = '90px';
}
return dalg;
}
function makeFunc(dalg) {
dalg.addEventListener(
'click',
function (event) { event.stopPropagation(); },
false
);
dalg.querySelector('input[value="Cancel"]').addEventListener(
'click',
function () { dalg.style.display = 'none'; },
false
);
dalg.querySelector('input[value="Cancel"]').addEventListener(
'mouseenter',
function (event) { event.target.style.backgroundColor = 'rgb(170, 170, 170)'; },
false
);
dalg.querySelector('input[value="Cancel"]').addEventListener(
'mouseleave',
function (event) { event.target.style.backgroundColor = 'rgb(190, 190, 190)'; },
false
);
dalg.querySelector('input[value="Set default"]').addEventListener(
'click',
function () {
for (var i = 0; i < ORIG_FONTS.length; ++i) {
dalg.querySelector('input[name="orig' + i + '"]').value = ORIG_FONTS[i];
dalg.querySelector('input[name="repld' + i + '"]').value = REPLD_FONTS[i];
}
dalg.querySelector('input[name="mod_fw"][value="' + MOD_FW + '"]').checked = true;
dalg.querySelector('input[name="intl"]').value = INTL;
},
false
);
dalg.querySelector('input[value="Set default"]').addEventListener(
'mouseenter',
function (event) { event.target.style.backgroundColor = 'rgb(170, 170, 170)'; },
false
);
dalg.querySelector('input[value="Set default"]').addEventListener(
'mouseleave',
function (event) { event.target.style.backgroundColor = 'rgb(190, 190, 190)'; },
false
);
dalg.querySelector('input[value="Save & Close"]').addEventListener(
'click',
function () {
for (var i = 0; i < ORIG_FONTS.length; ++i) {
orig_fonts[i] = dalg.querySelector('input[name="orig' + i + '"]').value;
repld_fonts[i] = dalg.querySelector('input[name="repld' + i + '"]').value;
GM_setValue('orig' + i, orig_fonts[i]);
GM_setValue('repld' + i, repld_fonts[i]);
}
for (var e of dalg.querySelectorAll('input[name="mod_fw"]')) {
if (e.checked) {
mod_fw = +e.value;
break;
}
}
GM_setValue('mod_fw', mod_fw);
intl = +dalg.querySelector('input[name="intl"]').value;
GM_setValue('intl', intl);
dalg.style.display = 'none'; // style は変化する
},
false
);
dalg.querySelector('input[value="Save & Close"]').addEventListener(
'mouseenter',
function (event) { event.target.style.backgroundColor = 'rgb(170, 170, 170)'; },
false
);
dalg.querySelector('input[value="Save & Close"]').addEventListener(
'mouseleave',
function (event) { event.target.style.backgroundColor = 'rgb(190, 190, 190)'; },
false
);
}
function initGUI() {
for (var i = 0; i < ORIG_FONTS.length; ++i) {
if (GM_getValue('orig' + i) === undefined) {
GM_setValue('orig' + i, ORIG_FONTS[i]);
} else {
orig_fonts[i] = GM_getValue('orig' + i);
}
if (GM_getValue('repld' + i) === undefined) {
GM_setValue('repld' + i, REPLD_FONTS[i]);
} else {
repld_fonts[i] = GM_getValue('repld' + i);
}
}
if (GM_getValue('mod_fw') === undefined) {
GM_setValue('mod_fw', MOD_FW);
} else {
mod_fw = GM_getValue('mod_fw');
}
if (GM_getValue('intl') === undefined) {
GM_setValue('intl', INTL);
} else {
intl = GM_getValue('intl');
}
var dalg = makeDalg();
makeFunc(dalg);
document.body.appendChild(dalg);
GM_registerMenuCommand('Settings', function () {
if (dalg.style.display == 'none') {
for (var i = 0; i < ORIG_FONTS.length; ++i) {
dalg.querySelector('input[name="orig' + i + '"]').value = orig_fonts[i];
dalg.querySelector('input[name="repld' + i + '"]').value = repld_fonts[i];
}
dalg.querySelector('input[name="mod_fw"][value="' + mod_fw + '"]').checked = true;
dalg.querySelector('input[name="intl"]').value = intl;
dalg.style.display = 'block';
}
});
}
function replFF(elm) {
var ff_before = getComputedStyle(elm, null).fontFamily;
var ff_after = ff_before;
if (ff_before) {
for (var i = 0; i < orig_fonts.length; ++i) {
if (orig_fonts[i] == '') continue;
var re = new RegExp(orig_fonts[i], 'gi');
ff_after = ff_after.replace(re, repld_fonts[i]);
}
if (ff_before != ff_after) {
var sm = muts;
elm.style.fontFamily = ff_after;
muts = sm;
}
}
}
function modFW(elm) {
var orig_fw = +getComputedStyle(elm, null).fontWeight;
var s_mod_fw = mod_fw;
if (!elm.hasAttribute('data-' + MYNAME + '_mfw')) {
if ((orig_fw <= 100 && mod_fw < 0) || (orig_fw >= 900 && mod_fw > 0)) {
return;
} else {
if (orig_fw + mod_fw < 100) s_mod_fw = 100 - orig_fw;
if (orig_fw + mod_fw > 900) s_mod_fw = 900 - orig_fw;
}
} else {
orig_fw -= +elm.getAttribute('data-' + MYNAME + '_mfw');
if ((orig_fw <= 100 && mod_fw < 0) || (orig_fw >= 900 && mod_fw > 0)) {
s_mod_fw = 0;
} else {
if (orig_fw + mod_fw < 100) s_mod_fw = 100 - orig_fw;
if (orig_fw + mod_fw > 900) s_mod_fw = 900 - orig_fw;
}
}
var sm = muts;
elm.style.fontWeight = orig_fw + s_mod_fw;
elm.setAttribute('data-' + MYNAME + '_mfw', s_mod_fw);
muts = sm;
}
function traverse(node) {
var kids = node.childNodes;
if (node.nodeType == 1) { // 子孫を判別する為
replFF(node);
if (mod_fw != 9999) modFW(node);
}
for (var i = 0; i < kids.length; i++) {
var kid = kids.item(i);
if (kid.childNodes.length > 0) traverse(kid);
}
}
function loop() {
setTimeout(function () {
if (muts) {
muts = null; // 初期値がtrue、変更もしない
traverse(ROOT_E);
}
loop();
}, intl);
}
for (var i = 0; i < ORIG_FONTS.length; ++i) {
orig_fonts.push(ORIG_FONTS[i]);
}
for (var i = 0; i < REPLD_FONTS.length; ++i) {
repld_fonts.push(REPLD_FONTS[i]);
}
mod_fw = MOD_FW;
intl = INTL;
observer.observe(ROOT_E, {
childList:true, attributes:true, subtree:true, attributeFilter:['style']
});
if(!NO_GUI) initGUI();
loop();
})(); /* END */