/* jshint esversion: 8 */ // ==UserScript== // @name 字体渲染(自用脚本) // @namespace https://openuserjs.org/users/t3xtf0rm4tgmail.com // @version 2021.06.21.3 // @icon https://img.icons8.com/ios-filled/50/26e07f/font-style-formatting.png // @description 让每个页面的字体变得有质感,默认使用微软雅黑字体,亦可自定义设置多种中文字体,附加字体描边、字体重写、字体阴影、字体平滑、对特殊样式元素的过滤和许可等效果,脚本菜单中可使用设置界面进行参数设置,亦可对某域名下所有页面进行排除渲染。 // @supportURL https://github.com/F9y4ng/GreasyFork-Scripts/issues // @author F9y4ng // @include * // @grant GM_info // @grant GM_registerMenuCommand // @grant GM.registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_getValue // @grant GM.getValue // @grant GM_setValue // @grant GM.setValue // @compatible Chrome 兼容TamperMonkey, ViolentMonkey // @compatible Firefox 兼容Greasemonkey, TamperMonkey, ViolentMonkey // @compatible Opera 兼容TamperMonkey, ViolentMonkey // @compatible Safari 兼容Tampermonkey • Safari // @license GPL-3.0-only // @create 2020-11-24 // @copyright 2020-2021, F9y4ng // @run-at document-start // @downloadURL none // ==/UserScript== !(function () { "use strict"; /* customize */ const isdebug = false; // set "true" to debug scripts, May cause script response slower. const refreshTime = 1000; // Define data synchronous refresh time, unit is millisecond. /* Perfectly Compatible For Greasemonkey4.0+, TamperMonkey, ViolentMonkey * F9y4ng * 20210609 */ let GMsetValue, GMgetValue, GMregisterMenuCommand, GMunregisterMenuCommand; const GMinfo = GM_info; const handlerInfo = GMinfo.scriptHandler; const isGM = Boolean(handlerInfo.toLowerCase() === "greasemonkey"); const debug = isdebug ? console.log.bind(console) : () => {}; const error = isdebug ? console.error.bind(console) : () => {}; const defCon = { scriptName: GMinfo.script.name, supportURL: GMinfo.script.supportURL, randString: (n, v, r, s = "") => { // v: true for only letters. let a = "0123456789"; let b = "abcdefghijklmnopqrstuvwxyz"; let c = b.toUpperCase(); n = Number.isFinite(n) ? n : 10; v ? (r = b + c) : (r = a + b + a + c); for (; n > 0; --n) { s += r[Math.floor(Math.random() * r.length)]; } return s; }, }; defCon.rndClass = defCon.randString(10, true); defCon.rndId = defCon.randString(12, true); if (isGM) { GMsetValue = GM.setValue; GMgetValue = GM.getValue; GMregisterMenuCommand = GM.registerMenuCommand; GMunregisterMenuCommand = () => {}; } else { GMsetValue = GM_setValue; GMgetValue = GM_getValue; GMregisterMenuCommand = GM_registerMenuCommand; GMunregisterMenuCommand = GM_unregisterMenuCommand; } /* Color Picker init */ ~(function (window, document) { let type = window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML"; let picker; let slide; let hueOffset = 15; let svgNS = "http://www.w3.org/2000/svg"; let colorpickerHTMLSnippet = [ '
', '
', '
', "
", '
', '
', '
', "
", ].join(""); function mousePosition(evt) { if (window.event && window.event.contentOverflow !== undefined) { return { x: window.event.offsetX, y: window.event.offsetY }; } if (evt.offsetX !== undefined && evt.offsetY !== undefined) { return { x: evt.offsetX, y: evt.offsetY }; } let wrapper = evt.target.parentNode.parentNode; return { x: evt.layerX - wrapper.offsetLeft, y: evt.layerY - wrapper.offsetTop }; } function $(el, attrs, children) { el = document.createElementNS(svgNS, el); for (let key in attrs) { el.setAttribute(key, attrs[key]); } if (Object.prototype.toString.call(children) !== "[object Array]") { children = [children]; } let i = 0; let len = (children[0] && children.length) || 0; for (; i < len; i++) { el.appendChild(children[i]); } return el; } if (type === "SVG") { slide = $("svg", { xmlns: "http://www.w3.org/2000/svg", version: "1.1", width: "100%", height: "100%" }, [ $( "defs", {}, $( "linearGradient", { id: "gradient-hsv", x1: "0%", y1: "100%", x2: "0%", y2: "0%", }, [ $("stop", { offset: "0%", "stop-color": "#FF0000", "stop-opacity": "1" }), $("stop", { offset: "13%", "stop-color": "#FF00FF", "stop-opacity": "1" }), $("stop", { offset: "25%", "stop-color": "#8000FF", "stop-opacity": "1" }), $("stop", { offset: "38%", "stop-color": "#0040FF", "stop-opacity": "1" }), $("stop", { offset: "50%", "stop-color": "#00FFFF", "stop-opacity": "1" }), $("stop", { offset: "63%", "stop-color": "#00FF40", "stop-opacity": "1" }), $("stop", { offset: "75%", "stop-color": "#0BED00", "stop-opacity": "1" }), $("stop", { offset: "88%", "stop-color": "#FFFF00", "stop-opacity": "1" }), $("stop", { offset: "100%", "stop-color": "#FF0000", "stop-opacity": "1" }), ] ) ), $("rect", { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#gradient-hsv)", }), ]); picker = $("svg", { xmlns: "http://www.w3.org/2000/svg", version: "1.1", width: "100%", height: "100%" }, [ $("defs", {}, [ $( "linearGradient", { id: "gradient-black", x1: "0%", y1: "100%", x2: "0%", y2: "0%", }, [ $("stop", { offset: "0%", "stop-color": "#000000", "stop-opacity": "1" }), $("stop", { offset: "100%", "stop-color": "#CC9A81", "stop-opacity": "0" }), ] ), $( "linearGradient", { id: "gradient-white", x1: "0%", y1: "100%", x2: "100%", y2: "100%", }, [ $("stop", { offset: "0%", "stop-color": "#FFFFFF", "stop-opacity": "1" }), $("stop", { offset: "100%", "stop-color": "#CC9A81", "stop-opacity": "0" }), ] ), ]), $("rect", { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#gradient-white)", }), $("rect", { x: "0", y: "0", width: "100%", height: "100%", fill: "url(#gradient-black)", }), ]); } else if (type === "VML") { slide = [ '
', '', '', "", "
", ].join(""); picker = [ '
', '', '', "", '', '', "", "
", ].join(""); if (!document.namespaces.v) { document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML"); } } function hsv2rgb(hsv) { let R, G, B, X, C; let h = (hsv.h % 360) / 60; C = hsv.v * hsv.s; X = C * (1 - Math.abs((h % 2) - 1)); R = G = B = hsv.v - C; h = ~~h; R += [C, X, 0, 0, X, C][h]; G += [X, C, C, X, 0, 0][h]; B += [0, 0, X, C, C, X][h]; let r = Math.floor(R * 255); let g = Math.floor(G * 255); let b = Math.floor(B * 255); return { r: r, g: g, b: b, hex: "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1) }; } function rgb2hsv(rgb) { let r = rgb.r; let g = rgb.g; let b = rgb.b; if (rgb.r > 1 || rgb.g > 1 || rgb.b > 1) { r /= 255; g /= 255; b /= 255; } let H, S, V, C; V = Math.max(r, g, b); C = V - Math.min(r, g, b); H = C === 0 ? null : V === r ? (g - b) / C + (g < b ? 6 : 0) : V === g ? (b - r) / C + 2 : (r - g) / C + 4; H = (H % 6) * 60; S = C === 0 ? 0 : C / V; return { h: H, s: S, v: V }; } function slideListener(ctx, slideElement, pickerElement) { return function (evt) { evt = evt || window.event; evt.stopPropagation(); let mouse = mousePosition(evt); ctx.h = (mouse.y / slideElement.offsetHeight) * 360 + hueOffset; ctx.s = ctx.v = 1; let c = hsv2rgb({ h: ctx.h, s: 1, v: 1 }); pickerElement.style.backgroundColor = c.hex; ctx.callback && ctx.callback(c.hex, { h: ctx.h - hueOffset, s: ctx.s, v: ctx.v }, { r: c.r, g: c.g, b: c.b }, undefined, mouse); }; } function pickerListener(ctx, pickerElement) { return function (evt) { evt = evt || window.event; let mouse = mousePosition(evt); let width = pickerElement.offsetWidth; let height = pickerElement.offsetHeight; ctx.s = mouse.x / width; ctx.v = (height - mouse.y) / height; let c = hsv2rgb(ctx); ctx.callback && ctx.callback(c.hex, { h: ctx.h - hueOffset, s: ctx.s, v: ctx.v }, { r: c.r, g: c.g, b: c.b }, mouse); }; } let uniqID = 0; class ColorPicker { constructor(slideElement, pickerElement, callback) { // new ColorPicker(slideElement, pickerElement, callback) this.h = 0; this.s = 1; this.v = 1; if (!callback) { let element = slideElement; element.innerHTML = colorpickerHTMLSnippet; this.slideElement = element.getElementsByClassName("slide")[0]; this.pickerElement = element.getElementsByClassName("picker")[0]; let slideIndicator = element.getElementsByClassName("slide-indicator")[0]; let pickerIndicator = element.getElementsByClassName("picker-indicator")[0]; ColorPicker.fixIndicators(slideIndicator, pickerIndicator); this.callback = function (hex, hsv, rgb, pickerCoordinate, slideCoordinate) { ColorPicker.positionIndicators(slideIndicator, pickerIndicator, slideCoordinate, pickerCoordinate); pickerElement(hex, hsv, rgb); }; } else { this.callback = callback; this.pickerElement = pickerElement; this.slideElement = slideElement; } if (type === "SVG") { let hsvGradient = slide.getElementsByTagName("linearGradient")[0]; let hsvRect = slide.getElementsByTagName("rect")[0]; hsvGradient.id = "gradient-hsv-" + uniqID; hsvRect.setAttribute("fill", "url(#" + hsvGradient.id + ")"); let blackAndWhiteGradients = picker.getElementsByTagName("linearGradient"); let whiteAndBlackRects = picker.getElementsByTagName("rect"); blackAndWhiteGradients[0].id = "gradient-black-" + uniqID; blackAndWhiteGradients[1].id = "gradient-white-" + uniqID; whiteAndBlackRects[0].setAttribute("fill", "url(#" + blackAndWhiteGradients[1].id + ")"); whiteAndBlackRects[1].setAttribute("fill", "url(#" + blackAndWhiteGradients[0].id + ")"); this.slideElement.appendChild(slide.cloneNode(true)); this.pickerElement.appendChild(picker.cloneNode(true)); uniqID++; } else { this.slideElement.innerHTML = slide; this.pickerElement.innerHTML = picker; } addEventListener(this.slideElement, "click", slideListener(this, this.slideElement, this.pickerElement)); addEventListener(this.pickerElement, "click", pickerListener(this, this.pickerElement)); enableDragging(this, this.slideElement, slideListener(this, this.slideElement, this.pickerElement)); enableDragging(this, this.pickerElement, pickerListener(this, this.pickerElement)); } setHsv(hsv) { return setColor(this, hsv); } setRgb(rgb) { return setColor(this, rgb2hsv(rgb), rgb); } setHex(hex) { return setColor(this, ColorPicker.hex2hsv(hex), undefined, hex); } static hsv2rgb(hsv) { let rgbHex = hsv2rgb(hsv); delete rgbHex.hex; return rgbHex; } static hsv2hex(hsv) { return hsv2rgb(hsv).hex; } static rgb2hex(rgb) { return hsv2rgb(rgb2hsv(rgb)).hex; } static hex2hsv(hex) { return rgb2hsv(ColorPicker.hex2rgb(hex)); } static hex2rgb(hex) { return { r: parseInt(hex.substr(1, 2), 16), g: parseInt(hex.substr(3, 2), 16), b: parseInt(hex.substr(5, 2), 16) }; } static positionIndicators(slideIndicator, pickerIndicator, mouseSlide, mousePicker) { if (mouseSlide) { pickerIndicator.style.left = "auto"; pickerIndicator.style.right = "0px"; pickerIndicator.style.top = "0px"; slideIndicator.style.top = mouseSlide.y - slideIndicator.offsetHeight / 2 + "px"; } if (mousePicker) { pickerIndicator.style.top = mousePicker.y - pickerIndicator.offsetHeight / 2 + "px"; pickerIndicator.style.left = mousePicker.x - pickerIndicator.offsetWidth / 2 + "px"; } } static fixIndicators(slideIndicator, pickerIndicator) { pickerIndicator.style.pointerEvents = "none"; slideIndicator.style.pointerEvents = "none"; } } function addEventListener(element, event, listener) { if (element.attachEvent) { element.attachEvent("on" + event, listener); } else if (element.addEventListener) { element.addEventListener(event, listener, false); } } function enableDragging(ctx, element, listener) { let mousedown = false; addEventListener(element, "mousedown", function (evt) { mousedown = true; }); addEventListener(element, "mouseup", function (evt) { mousedown = false; }); addEventListener(element, "mouseout", function (evt) { mousedown = false; }); addEventListener(element, "mousemove", function (evt) { if (mousedown) { listener(evt); } }); } ColorPicker.rgb2hsv = rgb2hsv; function setColor(ctx, hsv, rgb, hex) { ctx.h = hsv.h % 360; ctx.s = hsv.s; ctx.v = hsv.v; let c = hsv2rgb(ctx); let mouseSlide = { y: (ctx.h * ctx.slideElement.offsetHeight) / 360, x: 0, }; let pickerHeight = ctx.pickerElement.offsetHeight; let mousePicker = { x: ctx.s * ctx.pickerElement.offsetWidth, y: pickerHeight - ctx.v * pickerHeight, }; ctx.pickerElement.style.backgroundColor = hsv2rgb({ h: ctx.h, s: 1, v: 1 }).hex; ctx.callback && ctx.callback(hex || c.hex, { h: ctx.h, s: ctx.s, v: ctx.v }, rgb || { r: c.r, g: c.g, b: c.b }, mousePicker, mouseSlide); return ctx; } window.ColorPicker = ColorPicker; })(window, window.document); /* new DialogBox */ class DialogBox { constructor({ titleText = "Error", messageText = "Something unexpected has gone wrong. If the problem persists, contact your administrator", trueButtonText = "OK", falseButtonText = null, neutralButtonText = null, } = {}) { this.titleText = titleText; this.messageText = messageText; this.trueButtonText = trueButtonText; this.falseButtonText = falseButtonText; this.neutralButtonText = neutralButtonText; this.hasFalse = falseButtonText !== null; this.hasNeutral = neutralButtonText !== null; this.dialog = undefined; this.trueButton = undefined; this.falseButton = undefined; this.neutralButton = undefined; this.parent = document.body; this._createDialog(this); this._appendDialog(); } _createDialog(context) { this.dialog = document.createElement("div"); this.dialog.classList.add("dialog-box"); this.dialog.style.opacity = 0; const title = document.createElement("div"); title.textContent = this.titleText; title.classList.add("dialog-box-title"); this.dialog.appendChild(title); const question = document.createElement("div"); question.innerHTML = this.messageText; question.classList.add("dialog-box-message"); this.dialog.appendChild(question); const buttonContainer = document.createElement("div"); buttonContainer.classList.add("dialog-box-button-container"); this.dialog.appendChild(buttonContainer); this.trueButton = document.createElement("a"); this.trueButton.classList.add("dialog-box-button", "dialog-box-button--true"); this.trueButton.textContent = this.trueButtonText; this.trueButton.addEventListener("click", function () { context._destroy(); }); buttonContainer.appendChild(this.trueButton); if (this.hasFalse) { this.falseButton = document.createElement("a"); this.falseButton.classList.add("dialog-box-button", "dialog-box-button--false"); this.falseButton.textContent = this.falseButtonText; this.falseButton.addEventListener("click", function () { context._destroy(); }); buttonContainer.appendChild(this.falseButton); } if (this.hasNeutral) { this.neutralButton = document.createElement("a"); this.neutralButton.classList.add("dialog-box-button", "dialog-box-button--neutral"); this.neutralButton.textContent = this.neutralButtonText; this.neutralButton.addEventListener("click", function () { context._destroy(); }); buttonContainer.appendChild(this.neutralButton); } } _appendDialog() { const diag = this.dialog; if (this.dialog) { this.parent.appendChild(diag); setTimeout(function () { diag.style.opacity = 1; }, 0); } } _destroy() { if (this.dialog) { this.parent.removeChild(this.dialog); delete this; } } respond() { return new Promise((resolve, reject) => { const somethingWentWrongUponCreation = !this.dialog || !this.trueButton; if (somethingWentWrongUponCreation) { reject(new Error("Something went wrong upon modal creation")); } this.trueButton.addEventListener("click", () => { resolve(true); }); if (this.hasFalse) { this.falseButton.addEventListener("click", () => { resolve(false); }); } }); } } /* Slider Movements init */ let Slider = {}; Slider.scope = {}; Slider.createTemplateTagFirstArg = function (e) { return (e.raw = e); }; Slider.createTemplateTagFirstArgWithRaw = function (e, f) { e.raw = f; return e; }; !(function (e) { class f { constructor(a, c) { let b = void 0 === c ? {} : c; c = void 0 === b.size ? 10 : b.size; let d = void 0 === b.val ? 0 : b.val; let g = void 0 === b.precision ? 0 : b.precision; let h = void 0 === b.range ? 1 : b.range; let k = void 0 === b.getVal ? function () {} : b.getVal; let l = void 0 === b.drag ? !0 : b.drag; let m = void 0 === b.direction ? "horizontal" : b.direction; b = void 0 === b.tip ? !1 : b.tip; if (!a) { error("//-> \u5fc5\u987b\u6307\u5b9a\u5b9e\u4f8b\u5bf9\u8c61\u7684\u5bb9\u5668\uff01"); } this.container = document.querySelector(a); this.size = c; this.val = d; this.precision = g; this.range = h; this.getVal = k; this.drag = l; this.direction = m; if (typeof b === "object") { this.tip = b || { trigger: "show", align: "top", }; } else if ("boolean" !== typeof b) { error("//-> tip\u914d\u7f6e\u9519\u8bef"); } this.initialize(); } initialize() { if ( 0 > this.size || 0 > this.val || 100 < this.val || 0 > this.precision || 4 < this.precision || ("horizontal" !== this.direction && "vertical" !== this.direction) || !this.container || ("boolean" !== typeof this.drag && "object" !== typeof this.drag) ) { return error("//-> \u53c2\u6570\u914d\u7f6e\u9519\u8bef\uff01"); } this.rander(); this.renderLine(); } rander() { this.bgBar = document.createElement("div"); this.bgLine = document.createElement("div"); this.btnTip = document.createElement("div"); let a = this.bgBar; let c = this.container; let b = this.bgLine; let d = this.btnTip; switch (this.direction) { case "horizontal": a.classList.add("ProgressBar"); a.style.height = this.size + "px"; a.style.width = "100%"; a.style.borderRadius = this.size / 2 + "px"; b.appendChild(d); break; case "vertical": a.classList.add("ProgressBar"); a.style.width = this.size + "px"; a.style.height = "100%"; a.style.borderRadius = this.size / 2 + "px"; d.classList.add("vertical"); b.appendChild(d); } d.classList.add("btnl"); d.style.width = this.size + "px"; d.style.height = this.size + "px"; b.classList.add("ProgressLine"); b.style.borderRadius = this.size / 2 + "px"; a.appendChild(b); c.appendChild(a); this.drag ? this.Dragdrop() : this.btnTip.classList.add("disable"); (this.tip || typeof this.tip === "object") && this.openTip(); this.onLoading(); } Dragdrop() { let a = this; let c = this.bgBar; let b = function (d) { a.getPos(d); }; c.addEventListener("mousedown", function (d) { document.addEventListener("mousemove", b); a.getPos(d); }); document.addEventListener("mouseup", function (d) { document.removeEventListener("mousemove", b); }); c.addEventListener("touchstart", function (d) { document.addEventListener("touchmove", b); a.getPos(d); }); document.addEventListener("touchend", function (d) { document.removeEventListener("touchmove", b); }); } getPos(a) { typeof a.touches === "undefined" && (a.preventDefault(), a.stopPropagation()); a.touches && (a = a.touches[0]); this.oldVal = this.val; let b, c; switch (this.direction) { case "horizontal": a = a.clientX + this.size / 2; c = this.bgBar.clientWidth; b = this.getElementLeft(this.bgBar); this.val = ((a - b - this.size) / (c - this.size)) * 100; break; case "vertical": a = a.clientY + this.size / 2; c = this.bgBar.clientHeight; b = this.getElementTop(this.bgBar); this.val = 100 - ((a - b - this.size) / (c - this.size)) * 100; } this.val = Math.max(0, this.val); this.val = Math.min(100, this.val); this.renderLine(); this.eventVal(); } getElementLeft(a) { let c = a.offsetLeft; for (a = a.offsetParent; null !== a; a) { c += a.offsetLeft; a = a.offsetParent; } return c; } getElementTop(a) { let c = a.offsetTop; for (a = a.offsetParent; null !== a; a) { c += a.offsetTop; a = a.offsetParent; } return c; } renderLine() { switch (this.direction) { case "horizontal": this.bgLine.style.width = ((this.bgBar.clientWidth - this.size) * this.val) / 100 + this.size + "px"; break; case "vertical": this.bgLine.style.height = ((this.bgBar.clientHeight - this.size) * this.val) / 100 + this.size + "px"; } } eventVal() { this.val = Number(this.val.toFixed(this.precision)); this.oldVal !== this.val && (this.getVal && this.getVal(this), this.tip || typeof this.tip === "object") && (this.tipBox.innerText = String(((this.val / 100) * this.range).toFixed(this.precision + 2))); } updateVal(a) { 0 > a || 100 < a || ((this.val = Number(a)), this.renderLine(), (this.val = Number(a.toFixed(this.precision))), !this.tip && "object" !== typeof this.tip) || (this.tipBox.innerText = String(((this.val / 100) * this.range).toFixed(this.precision + 2))); } openTip() { let a = this.btnTip; this.tipBox = document.createElement("span"); this.tipBox.classList.add("progressVal"); this.tipBox.innerText = String(((this.val / 100) * this.range).toFixed(this.precision + 2)); a.appendChild(this.tipBox); this.tip.trigger && this.tipConfig(); } tipConfig() { let a = this; switch (this.tip.trigger) { case "hover": this.tipBox.style.opacity = 0; this.bgBar.addEventListener("mouseenter", function () { return (a.tipBox.style.opacity = 1); }); this.bgBar.addEventListener("mouseleave", function () { return (a.tipBox.style.opacity = 0); }); this.bgBar.addEventListener("touchstart", function () { return (a.tipBox.style.opacity = 1); }); this.bgBar.addEventListener("touchend", function () { return (a.tipBox.style.opacity = 0); }); break; case "show": this.tipBox.style.opacity = 1; } switch (this.tip.align) { case "bottom": this.tipBox.classList.add("bottom"); break; case "left": this.tipBox.classList.add("left"); break; case "right": this.tipBox.classList.add("right"); } } onLoading() { let a = (this.btnLoading = document.createElement("span")); let c = this.btnTip; a.classList.add("loading"); c.appendChild(a); a.style.width = c.offsetWidth + "px"; a.style.height = c.offsetHeight + "px"; } onLoad(a, c) { c = void 0 === c ? function () {} : c; if ("boolean" !== typeof a) { error("//-> onload\u914d\u7f6e\u9519\u8bef"); } a && (this.btnLoading.style.display = "block"); c(this); } } e.Progress = f; })(window); function checkdraw(b, a, c) { b.value = ((a.val / 100) * a.range).toFixed(a.precision + 2); b.addEventListener("blur", function () { this.value <= a.range ? ((this.value = Number(this.value.match(c)).toFixed(a.precision + 2)), a.updateVal((100 * this.value) / a.range)) : (this.value = ((a.val / 100) * a.range).toFixed(a.precision + 2)); }); } /* Font filtering & discriminating list */ let fontSet = function (s) { return { that: Array.prototype.slice.call(document.querySelectorAll(s), 0), stopPropagation: function (e) { e = e || window.event; if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; } }, hide: function () { fontSet(s).that.forEach(function (item) { item.style.cssText += "display:none"; }); }, show: function () { fontSet(s).that.forEach(function (item) { item.style.cssText += "display:block"; }); }, fdeleteList: function (fontData) { let ddRemove = function (dd) { let temp = dd.nextElementSibling; dd.remove(); if (temp !== null && temp.nodeName === "DD") { ddRemove(temp); } }; let selector = (function () { class selector { constructor(ch, en) { this.ch = ch; this.en = en; } } return selector; })(); let close = fontSet("#fontSelect .close"); close.that.forEach(function (item) { ddRemove(item.parentNode); let value = item.parentNode.children[1].value; let text = item.parentNode.children[0].innerHTML; fontData.push(new selector(text, value)); if (fontSet("#fontSelect .close").that.length === 0) { fontSet("#fontSelect .selector").that[0].parentNode.style.cssText += "display:none;"; } }); return Boolean(close.that.length); }, fsearchList: function (name) { let arr = []; fontSet("input[name=" + name + "]").that.forEach(item => { arr.push(item.value); }); return arr; }, fsearch: function (name, fontData) { let domId = fontSet(s).that[0]; let html = String( `
\ud83d\udd14温馨提示:

脚本预载了多种常用的、好看的中文字体,下拉菜单中所罗列的字体是您系统中已安装过的字体,没有安装过则不会显示。

在选择字体时,尽量减少字体种类。(请您注意)字体是按您选择的先后顺序进行优先渲染的,所以多选不如之选一个您最想要的。

` ); domId.innerHTML = html; fontSet("#fontSelect .selector").that[0].parentNode.style.cssText += "display:none;"; function clickEvent() { fontSet("#fontSelect .selectId dl dd").that.forEach(function (item) { item.onclick = function (e) { let value = this.attributes.value.value.toString(); if (value) { fontSet("#fontSelect .selector").that[0].innerHTML += String( `${this.innerHTML}×` ); fontSet(".selector").that[0].parentNode.style.cssText += "display:block;"; for (let i = 0; i < fontData.length; i++) { if (fontData[i].en === value) { fontData.splice(i, 1); i = fontData.length; } } removeFontSelector(); } fontSet(".selectId dl").hide(); fontSet("#fontSelect .selectId input").that[0].value = ""; e.stopPropagation(); }; }); } let ddRemove = function (dd) { let temp = dd.nextElementSibling; dd.remove(); if (temp !== null && temp.nodeName === "DD") { ddRemove(temp); } }; fontSet("#fontSelect .selectId input").that[0].oninput = function () { let val = this.value; let dd = fontSet("#fontSelect .selectId dl dd").that[0]; if (dd === "DD") { ddRemove(dd); } fontSet("#fontSelect .selectId dl").hide(); if (fontData.length > 0) { fontSet("#fontSelect .selectId dl").show(); let sear_1 = new RegExp(val); let judge_1 = false; fontSet("#fontSelect .selectId dl").that[0].innerHTML = ""; fontData.forEach(function (item) { if (sear_1.test(item.name)) { judge_1 = true; fontSet("#fontSelect .selectId dl").that[0].innerHTML += String( `
${item.ch}
` ); } }); if (!judge_1) { fontSet("#fontSelect .selectId dl").that[0].innerHTML = "
\u6682\u65E0\u6570\u636E
"; } clickEvent(); } }; fontSet("#fontSelect .selectId input").that[0].onclick = function (e) { let dd = fontSet("#fontSelect .selectId dl dd").that[0]; if (dd === "DD") { ddRemove(dd); } if (fontData.length === 0) { this.innerHTML = "暂无数据"; } else { fontSet("#fontSelect .selectId dl").show(); } fontSet("#fontSelect .selectId dl").that[0].innerHTML = ""; fontData.sort(function (a, b) { return a.en - b.en; }); fontData.forEach(function (item) { fontSet("#fontSelect .selectId dl").that[0].innerHTML += String( `
${item.ch}
` ); }); clickEvent(); e.stopPropagation(); }; let selector = (function () { class selector { constructor(ch, en) { this.ch = ch; this.en = en; } } return selector; })(); function removeFontSelector() { fontSet("#fontSelect .close").that.forEach(function (item) { item.onclick = function () { ddRemove(this.parentNode); let value = this.parentNode.children[1].value; let text = this.parentNode.children[0].innerHTML; fontData.push(new selector(text, value)); if (fontSet("#fontSelect .close").that.length === 0) { fontSet("#fontSelect .selector").that[0].parentNode.style.cssText += "display:none;"; } }; }); } document.onclick = function (e) { fontSet("#fontSelect .selectId dl").hide(); fontSet("#fontSelect .selectId input").that[0].value = ""; }; }, }; }; const fontCheck = new Set( [ { ch: "微软雅黑", en: "Microsoft YaHei" }, { ch: "微软正黑体", en: "Microsoft JhengHei" }, { ch: "苹方-简", en: "PingFang SC" }, { ch: "冬青黑体简", en: "Hiragino Sans GB" }, { ch: "兰亭黑-简", en: "Lantinghei SC" }, { ch: "儷黑 Pro", en: "LiHei Pro Medium" }, { ch: "翩翩体-简", en: "Hanzipen SC" }, { ch: "手札体-简", en: "Hannotate SC" }, { ch: "娃娃体-简", en: "Wawati SC" }, { ch: "魏碑-简", en: "Weibei SC" }, { ch: "行楷-简", en: "Xingkai SC" }, { ch: "雅痞-简", en: "Yapi SC" }, { ch: "圆体-简", en: "Yuanti SC" }, { ch: "华文黑体", en: "STHeiti" }, { ch: "华文楷体", en: "STKaiti" }, { ch: "华文细黑", en: "STXihei" }, { ch: "华文彩云", en: "STCaiyun" }, { ch: "华文琥珀", en: "STHupo" }, { ch: "华文新魏", en: "STXinwei" }, { ch: "华文隶书", en: "STLiti" }, { ch: "华文行楷", en: "STXingkai" }, { ch: "方正舒体", en: "FZShuTi" }, { ch: "方正姚体", en: "FZYaoti" }, { ch: "思源黑体", en: "Source Han Sans CN" }, { ch: "思源宋体", en: "Source Han Serif SC" }, { ch: "文泉驿微米黑", en: "WenQuanYi Micro Hei" }, { ch: "汉仪旗黑 40S", en: "HYQihei 40S" }, { ch: "汉仪旗黑 50S", en: "HYQihei 50S" }, { ch: "汉仪旗黑 60S", en: "HYQihei 60S" }, { ch: "幼圆", en: "YouYuan" }, { ch: "楷体", en: "KaiTi" }, { ch: "仿宋", en: "FangSong" }, { ch: "隶书", en: "LiSu" }, ].sort() ); class isSupportFontFamily { constructor() { let baseFonts = ["monospace", "sans-serif", "serif"]; let testString = "mmmmmmmnnoowwllii测试"; let testSize = "72px"; let h = document.getElementsByTagName("body")[0]; let s = document.createElement("span"); s.style.fontSize = testSize; s.innerHTML = testString; let defaultWidth = {}; let defaultHeight = {}; for (let index in baseFonts) { s.style.fontFamily = baseFonts[index]; h.appendChild(s); defaultWidth[baseFonts[index]] = s.offsetWidth; defaultHeight[baseFonts[index]] = s.offsetHeight; h.removeChild(s); } function detect(font) { let detected = false; for (let index in baseFonts) { s.style.fontFamily = font + "," + baseFonts[index]; h.appendChild(s); let matched = s.offsetWidth !== defaultWidth[baseFonts[index]] || s.offsetHeight !== defaultHeight[baseFonts[index]]; h.removeChild(s); detected = detected || matched; } return detected; } this.detect = detect; } } /* define default value */ const defValue = { fontSelect: `"Microsoft YaHei",Arial,Helvetica,sans-serif`, fontFace: true, fontStroke: 0.04, fontShadow: 1.0, shadowColor: "#d4d4d4", fontSmooth: true, fontCSS: `:not(.fa,.mi):not([class*="nav"]):not([class*="icon"]):not([class*="logo"]):not([class*="code"])`, fontEx: `pre *, code *,* input,* textarea,* kbd,* i,* em`, }; const feedback = defCon.supportURL ? defCon.supportURL : "https://greasyfork.org/scripts/416688/feedback"; const CONST = {}; /* Start specific operation */ !(async function () { // Get Promise Value let temp = await GMgetValue("_fonts_set_"); let exSite = await GMgetValue("_Exclude_site_"); let obj = ["workstation-xi"].sort(); /* Fixed data error, next versions will remove it. START */ /* Temporary */ function isJSON(str) { /* Temporary */ try { /* Temporary */ let obj = JSON.parse(str); /* Temporary */ if (typeof obj === "object" && obj) { /* Temporary */ return true; } /* Temporary */ else { /* Temporary */ return false; } /* Temporary */ } /* Temporary */ catch (e) { /* Temporary */ return false; } /* Temporary */ } /* Temporary */ /* Temporary */ if (isJSON(exSite)) { /* Temporary */ GMsetValue("_Exclude_site_", obj); } /* Temporary */ /* Fixed data error, next versions will remove it. END */ if (!temp && !exSite) { sessionStorage.setItem("_temp_", 1); sessionStorage.setItem("_exSite_", 1); } else { setInterval(async () => { exSite = await GMgetValue("_Exclude_site_"); }, refreshTime); } if (Number(sessionStorage.getItem("_temp_")) && Number(sessionStorage.getItem("_exSite_"))) { setTimeout(async () => { let dialog = new DialogBox({ trueButtonText: "好,去看看", falseButtonText: "不,算了吧", messageText: `

您好,这是您首次使用新版的字体渲染脚本,新版脚本可通过脚本菜单进行全局设置,可排除不需要渲染的域名等高级功能,告别旧版需要修改代码的大难题,具体功能敬请试用。

稍后,将为您打开新版脚本的介绍页面,您需要去看一下吗?

`, titleText: "温馨提示", }); sessionStorage.clear(); if (await dialog.respond()) { window.open( `https://openuserjs.org/scripts/t3xtf0rm4tgmail.com/%E5%AD%97%E4%BD%93%E6%B8%B2%E6%9F%93%EF%BC%88%E8%87%AA%E7%94%A8%E8%84%9A%E6%9C%AC%EF%BC%89`, "Guide" ); } dialog = null; }, 100); } /* Exclude site */ let siteIndex; if (!exSite) { GMsetValue("_Exclude_site_", obj); exSite = obj; } else { for (let i = 0; i < exSite.length; i++) { if (exSite[i] === location.hostname) { siteIndex = i; break; } } } /* Menus Insert */ try { let Font_Set, Exclude_site, Feed_Back; Font_Set ? GMunregisterMenuCommand(Font_Set) : debug("No Font_Set"); Exclude_site ? GMunregisterMenuCommand(Exclude_site) : debug("No Exclude_site"); Feed_Back ? GMunregisterMenuCommand(Feed_Back) : debug("No Feed_Back"); if (window.self === window.top) { if (siteIndex === undefined) { Font_Set = GMregisterMenuCommand("\ufff0\ud83c\udf13 字体渲染设置", () => { document.querySelector(`#${defCon.rndId}`).style = "visibility: visible;"; }); Exclude_site = GMregisterMenuCommand(`\ufff1\ud83d\udeab 排除渲染 ${location.hostname}`, async () => { exSite.push(location.hostname); GMsetValue("_Exclude_site_", exSite); let dialog = new DialogBox({ trueButtonText: "确 定", messageText: "

" + location.hostname + " 已禁止字体渲染!

确定后页面将自动刷新!

", titleText: "禁止字体渲染", }); if (await dialog.respond()) { dialog = null; location.reload(); } }); } else { Exclude_site = GMregisterMenuCommand(`\ufff1\ud83c\udf40 重新渲染 ${location.hostname}`, async () => { exSite.splice(siteIndex, 1); GMsetValue("_Exclude_site_", exSite); let dialog = new DialogBox({ trueButtonText: "确 定", messageText: "

" + location.hostname + " 重新开启字体渲染!

确定后页面将自动刷新!

", titleText: "恢复字体渲染", }); if (await dialog.respond()) { dialog = null; location.reload(); } }); } Feed_Back = GMregisterMenuCommand("\ufff9\ud83e\udde1 建议反馈", () => { window.open(feedback, "feedback"); }); } } catch (e) { error("%c[Error]%c\n%s", "font-weight:bold;color:red", "font-weight:bold;color:darkred", e); } /* Set Default Value & initialize */ if (!temp) { saveDate("_fonts_set_", { fontSelect: defValue.fontSelect, fontFace: defValue.fontFace, fontStroke: defValue.fontStroke, fontShadow: defValue.fontShadow, shadowColor: defValue.shadowColor, fontSmooth: defValue.fontSmooth, fontCSS: defValue.fontCSS, fontEx: defValue.fontEx, }); CONST.fontSelect = defValue.fontSelect; CONST.fontFace = defValue.fontFace; CONST.fontStroke = defValue.fontStroke; CONST.fontShadow = defValue.fontShadow; CONST.shadowColor = defValue.shadowColor; CONST.fontSmooth = defValue.fontSmooth; CONST.fontCSS = defValue.fontCSS; CONST.fontEx = defValue.fontEx; } else { const fontValue = JSON.parse(temp); CONST.fontSelect = fontValue.fontSelect; CONST.fontFace = fontValue.fontFace; CONST.fontStroke = fontValue.fontStroke; CONST.fontShadow = fontValue.fontShadow; CONST.shadowColor = fontValue.shadowColor; CONST.fontSmooth = fontValue.fontSmooth; CONST.fontCSS = fontValue.fontCSS; CONST.fontEx = fontValue.fontEx; } /* Operation of CSS value */ let shadow = ""; const shadow_r = parseFloat(CONST.fontShadow); const shadow_c = CONST.shadowColor; if (!isNaN(shadow_r) && shadow_r > 0 && shadow_r <= 8) { shadow = `text-shadow:-1px 1px ${shadow_r}px ${shadow_c},1px 1px ${shadow_r}px ${shadow_c},1px -1px ${shadow_r}px ${shadow_c},-1px -1px ${shadow_r}px ${shadow_c};`; } let stroke = ""; const stroke_r = parseFloat(CONST.fontStroke); if (!isNaN(stroke_r) && stroke_r > 0 && stroke_r <= 1.0) { stroke = `-webkit-text-stroke:${stroke_r}px;text-stroke:${stroke_r}px;-webkit-text-fill-color:currentcolor;text-fill-color:currentcolor;`; } let smoothing = ""; const smooth_i = Boolean(CONST.fontSmooth); if (smooth_i) { smoothing = `-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;`; } const fontfamily = `font-family:${CONST.fontSelect.toString()};`; let refont = CONST.fontSelect.toString().split(",")[0]; refont = refont ? refont.replace(/"|'/g, "") : ""; let fontface = ""; if (CONST.fontFace) { fontface = refont ? `@font-face{font-family:"宋体";src:local("${refont}")}@font-face{font-family:"新宋体";src:local("${refont}")}@font-face{font-family:"黑体";src:local("${refont}")}@font-face{font-family:"Microsoft YaHei UI";src:local("${refont}")}@font-face{font-family:"Segoe UI";src:local("${refont}")}@font-face{font-family:"Microsoft YaHei";src:local("${refont}")}@font-face{font-family:"微软雅黑";src:local("${refont}")}@font-face{font-family:"PingFang SC";src:local("${refont}")}@font-face{font-family:Tahoma;src:local("${refont}")}@font-face{font-family:Arial;src:local("${refont}")}@font-face{font-family:Helvetica;src:local("${refont}")}` : ``; } const cssexlude = CONST.fontEx; const exclude = `${cssexlude}{text-stroke:0!important;-webkit-text-stroke:0!important;text-shadow:0 0 0 #fff!important}`; const cssfun = CONST.fontCSS; let tshadow = ""; if (siteIndex === undefined) { tshadow = `${exclude}${cssfun}{${shadow}${stroke}${smoothing}${fontfamily}}${fontface}`; } const fontStyle = `.dialog-box{max-width:400px;color:#444;z-index:9999999;border:2px solid #efefef;-moz-border-radius:24px;border-radius:24px}.dialog-box *,.dialog-box *:hover{text-stroke:0!important;-webkit-text-stroke:0!important;text-shadow:0 0 0 #fff!important}.dialog-box-button--false{background:#d93223;color:#fff;border:1px solid #d93223;-moz-border-radius:6px;border-radius:6px;font-size:14px!important}.dialog-box-button--true{background:#038c5a;color:#fff;border:1px solid #038c5a;-moz-border-radius:6px;border-radius:6px;font-size:14px!important}.dialog-box-button--neutral{background:#777;color:#fff;border:1px solid #777;-moz-border-radius:6px;border-radius:6px;font-size:14px!important}.dialog-box{width:100%;display:block;position:fixed;right:-180px;top:500px;transform:translate(-50%,-50%);background:#fff;-webkit-box-shadow:0 0 10px 0 rgba(0,0,0,.3);-moz-box-shadow:0 0 10px 0 rgba(0,0,0,.3);box-shadow:0 0 10px 0 rgba(0,0,0,.3);border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;overflow:hidden;transition:opacity .3s}.dialog-box-message{color:#444;padding:10px;margin:10px;font-size:16px;font-weight:300}.dialog-box-message p{line-height:160%;margin:5px 0}.dialog-box-title{background:#efefef;margin-top:0;padding:12px;font-size:20px;font-weight:700;width:100%}.dialog-box-button{min-width:20%;letter-spacing:0;text-align:center;cursor:pointer;padding:10px;display:inline-block;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;margin:0 1%;font-size:12px;font-weight:300;transition:opacity .5s}.dialog-box-button:hover{color:#fff;opacity:.8}.dialog-box-button-container{text-align:right;padding:2.5%;background:#efefef;color:#ffffff;}#color-picker{display:none;min-height:205px;min-width:250px;z-index:999999;margin-top:40px;position:fixed}.picker-wrapper,.slide-wrapper{position:relative;float:left}.picker-indicator,.slide-indicator{position:absolute;left:0;top:0;pointer-events:none}.picker,.slide{cursor:crosshair;float:left}.cp-default{background-color:#d1f2fb;padding:10px;box-shadow:0 0 10px #000;border-radius:6px;float:left}.cp-default .picker{width:200px;height:200px;border:2px solid #222}.cp-default .slide{width:30px;height:200px}.cp-default .slide-wrapper{margin-left:10px}.cp-default .picker-indicator{width:5px;height:5px;border:2px solid #00008b;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;opacity:.5;background-color:#fff}.cp-default .slide-indicator{width:100%;height:10px;left:-4px;opacity:.6;border:4px solid #add8e6;-moz-border-radius:4px;-o-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;background-color:#fff}body #fr-container{background:#f0f6ff;border-radius:6px;-moz-border-radius:6px;position:fixed;top:10px;right:20px}#fr-container *{text-stroke:0!important;-webkit-text-stroke:0!important;text-shadow:0 0 0 #fff!important}#fr-container{width:340px;z-index:9999999;padding:3px 8px;text-align:left;background-color:#fff;color:#333;font-size:16px;font-weight:900;-webkit-transition:all .1s ease-in;transition:all .1s ease-in;}#fr-container strong{display:block;margin-bottom:10px}#fr-container p{display:block;margin:0 0 10px 0;line-height:140%}#fr-container ul li{list-style:none;margin:3px 0;-webkit-box-sizing:content-box;box-sizing:content-box;border:none;float:none;cursor:default}#fr-container fieldset{border:2px groove #67a5df;-moz-border-radius:10px;border-radius:10px;padding:4px 9px 6px 9px;margin:2px;display:block;width:auto;height:auto;min-height:500px}#fr-container legend{line-height:20px;padding:0 8px;margin-bottom:0;font-size:16px;font-weight:700;font-family:"Microsoft YaHei",sans-serif;-webkit-box-sizing:content-box;box-sizing:content-box;width:auto!important;min-width:185px!important}#fr-container fieldset>ul{padding:0;margin:0}#fr-container .setting-title{color:#8b0000}@-webkit-keyframes rotation{from{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}.setting-title .Rotation{bottom:auto;top:auto;left:auto;right:auto;-webkit-transform:rotate(360deg);animation:rotation 5s linear infinite;-moz-animation:rotation 5s linear infinite;-webkit-animation:rotation 5s linear infinite;-o-animation:rotation 5s linear infinite}#fontSelect{padding:2px 10px;min-height:80px}#fontFace,#fontSmooth{padding:2px 10px;height:40px;width:calc(100% -10px);min-width:calc(100% -10px)}#shadowColor{padding:2px 10px;min-height:45px;margin:4px width: calc(100% - 10px)}#fontShadow{padding:2px 10px;height:70px}#fontStroke{padding:2px 10px;height:70px}#submitData{padding:2px 10px;height:40px}#submitData button{background-color:#67a5df;color:#fff;padding:5px;font-size:14px;font-weight:400;border:2px solid #6ba7e0;-moz-border-radius:6px;border-radius:6px;width:50px}#submitData .cancel,#submitData .reset{float:left;margin-right:10px}#submitData .fr-submit{float:right}#fontCSS,#fontEx{padding:2px 10px;min-height:110px}#fontCSS textarea,#fontEx textarea{width:100%;max-width:calc(100% - 15px)!important;height:60px;resize:none;border:2px solid #67a5df;-moz-border-radius:6px;border-radius:6px;-webkit-box-sizing:content-box;box-sizing:content-box;padding:5px;font-family:"Fira Code",Monaco,consolas,sans-serif;font-size:14px;font-weight:500;color:#0b5b9c;scrollbar-color:rgba(0,0,0,.6) rgba(0,0,0,.25);scrollbar-width:thin;scrollbar-arrow-color:#fff;scrollbar-face-color:#4c4c4c;scrollbar-highlight-color:#4c4c4c;scrollbar-shadow-color:#4c4c4c;scrollbar-track-color:#bfbfbf;scrollbar-3dlight-color:#4c4c4c;scrollbar-darkshadow-color:#4c4c4c;scrollbar-base-color:#4c4c4c}#fontCSS textarea::-webkit-scrollbar,#fontEx textarea::-webkit-scrollbar{width:5px;height:5px}#fontCSS textarea::-webkit-scrollbar-track,#fontEx textarea::-webkit-scrollbar-track{border-radius:5px;background-color:rgba(0,0,0,.25)}#fontCSS textarea::-webkit-scrollbar-thumb,#fontEx textarea::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(0,0,0,.6)}.fr_tooltip{position:relative}.fr_tooltip .fr_tooltiptext{visibility:hidden;z-index:9999;width:220px;max-width:220px;background-color:#54a2ec;border:2px solid #b8c4ce;font-weight:400;color:#fff;border-radius:6px;-moz-border-radius:6px;padding:10px;position:absolute;font-size:14px;opacity:.9;-moz-opacity:.9;display:none;-webkit-box-sizing:content-box;box-sizing:content-box}.fr_tooltip:hover .fr_tooltiptext{visibility:visible;display:block}.ps1{top:-32px;left:250px}.ps2{top:-20px;left:-250px}.ps4{top:25px}#fontSelect .selector a{font-weight:400;color:#111;text-decoration:none}#fontSelect .label{padding:2px 0;background:#67a5df;border-radius:2px;-moz-border-radius:2px;color:#fff;display:block;line-height:20px;height:24px;margin:2px 5px 2px 0;float:left;-webkit-box-sizing:content-box;box-sizing:content-box;font-weight:400}#fontSelect .label span{padding:5px}#fontSelect .close{padding:1px 2px 5px 2px!important;color:#fff;-webkit-box-sizing:content-box;box-sizing:content-box}#fontSelect .close:hover{background-color:#366694;border-radius:2px;-moz-border-radius:2px;color:tomato}#fontSelect .selectId{width:calc(100% - 42px)}#fontSelect .selectId label{display:block;margin:5px 0}#fontSelect .selectId input{height:36px!important;padding:1px 25px!important;text-indent:0;font-size:16px;width:100%;max-width:calc(100% - 10px);outline-color:#67a5df;border:2px solid #67a5df;border-radius:6px;-moz-border-radius:6px;-webkit-box-sizing:content-box;box-sizing:content-box}#fontSelect .selectId dl{position:fixed;z-index:1000;width:100%;max-width:180px;-webkit-box-sizing:content-box;box-sizing:content-box;background-color:#fff;border:2px solid #67a5df;border-radius:4px;-moz-border-radius:4px;margin:8px 0 0 0;padding:4px 25px;max-height:200px;font-size:18px;overflow-x:hidden;white-space:nowrap}#fontSelect .selectId dl dd{margin:0;padding:5px;font-weight:400}#fontSelect .selectId dl dd:hover{background-color:#67a5df;color:#fff}#selector{width:100%;max-width:100%}#fontSelect .selector{width:100%;max-width:calc(100% - 15px);overflow-y:auto;max-height:60px;border:2px solid #67a5df;border-radius:6px;-moz-border-radius:6px;padding:6px;-webkit-box-sizing:content-box;box-sizing:content-box}.checkbox{display:none!important}.checkbox+label{background-color:#fff;padding:11px 9px;border-radius:7px;display:inline-block;position:relative;background:#f7836d;width:58px;height:10px;box-shadow:inset 0 0 20px rgba(0,0,0,.1),0 0 10px rgba(245,146,146,.4);-webkit-box-sizing:content-box;box-sizing:content-box;word-wrap:normal!important}.checkbox+label:before{content:' ';position:absolute;background:#fff;top:0;z-index:999;left:0;width:24px;color:#fff;height:32px;border-radius:7px;-moz-border-radius:7px;box-shadow:0 0 1px rgba(0,0,0,.6);}.checkbox+label:after{content:'OFF';position:absolute;top:0;left:28px;font-size:1em;color:#fff;font-weight:700;padding:5px;border-radius:100px;-moz-border-radius:100px;-webkit-box-sizing:content-box;box-sizing:content-box}.checkbox:checked+label{-webkit-box-sizing:content-box;box-sizing:content-box;background:#67a5df;box-shadow:inset 0 0 20px rgba(0,0,0,.1),0 0 10px rgba(146,196,245,.4)}.checkbox:checked+label:after{content:'ON';left:10px;-webkit-box-sizing:content-box;box-sizing:content-box}.checkbox:checked+label:before{content:' ';position:absolute;z-index:999;left:52px;-webkit-box-sizing:content-box;box-sizing:content-box}#f-face label,#f-face+label:after,#f-face+label:before,#smooth label,#smooth+label:after,#smooth+label:before{-webkit-transition:all .1s ease-in;transition:all .1s ease-in;-webkit-box-sizing:content-box;box-sizing:content-box}#color-picker-show{float:left;display:block;margin-top:-6px}.cpicker{width:32px;height:32px;cursor:pointer;position:relative;border:2px solid #181a25;-moz-border-radius:4px;border-radius:4px;float:left;display:inline-block}.cpicker #color{width:125px;height:32px;text-indent:0;font-size:18px;-webkit-box-sizing:content-box;box-sizing:content-box;font-family:Impact,'Courier New',sans-serif!important;font-weight:400;border:#67a5df 2px solid;-moz-border-radius:4px;border-radius:4px;display:inline-block;padding:0 5px;margin-top:-2px;text-align:center}#fontShadow #shadowSize,#fontStroke #strokeSize{color:#111;width:56px;text-indent:0;margin-bottom:2px;float:right;height:32px;font-size:17px;font-family:Impact,'Courier New',sans-serif!important;border:#67a5df 2px solid;-moz-border-radius:4px;border-radius:4px;margin-right:2px;text-align:center;-webkit-box-sizing:content-box;box-sizing:content-box;padding:0}.progress{margin:2px;width:calc(100% - 10px)}.ProgressBar{background:#f0f0f0;margin:2px;width:250px;box-sizing:border-box;display:flex;align-items:flex-end;box-shadow:0 0 1px 1px rgba(0,0,0,.1) inset}.ProgressLine{width:100%;height:100%;position:relative;border-radius:15px;background:#67a5df}.ProgressLine .btnl{position:absolute;height:100%;right:0;border-radius:50%;font-size:8px;background:#67a5df;border:6px solid #fff;top:50%;transform:translate(6px,-50%);box-sizing:content-box!important;box-shadow:0 0 0 1px rgba(0,0,0,.2);display:flex;justify-content:center;align-items:center}.ProgressLine .btnl .disable{background:#ddd;border-color:#fafafa}.ProgressLine .btnl .loading{display:none;position:absolute;content:'';top:50%;left:50%;border-radius:50%;overflow:hidden;transform:translate(-50%,-50%);background:url(../images/loading1.gif);background-position:center center;background-size:130%;opacity:.5}@keyframes rate{0%{transform:translate(-50%,-50%) rotate(0)}100%{transform:translate(-50%,-50%) rotate(360deg)}}.vertical{top:0!important;left:50%!important;transform:translate(-50%,-6px)!important}.ProgressBar .progressVal{position:absolute;right:0;background:rgba(0,0,0,.4);text-align:center;width:45px;box-sizing:border-box;padding:0 4px;font-size:10px;color:#fff;height:20px;line-height:20px;border-radius:4px;top:-35px;left:50%;transform:translateX(-50%);transition:.5s linear}.ProgressBar .progressVal.bottom{top:auto;bottom:-35px}.ProgressBar .progressVal::after{position:absolute;content:'';border-width:5px 5px 0;border-style:solid;border-color:rgba(0,0,0,.4) transparent transparent;bottom:-5px;left:50%;transform:translateX(-50%)}.ProgressBar .progressVal.bottom::after{bottom:auto;top:-5px;border-width:0 5px 5px;border-style:solid;border-color:transparent transparent rgba(0,0,0,.4)}.ProgressBar .progressVal.left{top:auto;left:-40px}.ProgressBar .progressVal.left::after{top:50%;transform:translateY(-50%);left:auto;right:-5px;bottom:auto;border-width:5px 0 5px 5px;border-style:solid;border-color:transparent transparent transparent rgba(0,0,0,.4)}.ProgressBar .progressVal.right{top:auto;right:-85px;left:auto}.ProgressBar .progressVal.right::after{top:50%;transform:translateY(-50%);right:auto;left:-5px;bottom:auto;border-width:5px 5px 5px 0;border-style:solid;border-color:transparent rgba(0,0,0,.4) transparent transparent}`; const tHTML = String(`
${defCon.scriptName}
`); const tCSS = `@charset "UTF-8";` + tshadow + fontStyle; /* Insert HTML and CSS */ function insertHTML() { if (document.body !== null && document.querySelector(`#${defCon.rndId}`) === null) { let div = document.createElement("div"); div.id = defCon.rndId; div.style = "visibility:hidden;"; div.innerHTML = tHTML; try { document.getElementsByTagName("body")[0].appendChild(div); return true; } catch (e) { console.log(e); return false; } } } function RAF() { RAFInterval( () => { if (!document.querySelector(`.${defCon.rndClass}`)) { addStyle(tCSS, `${defCon.rndClass}`, "head"); } if (!document.querySelector(`#${defCon.rndId}`)) { insertHTML(); } }, 200, true ); } try { const callback = mutations => { mutations.forEach(mutation => { if (document.querySelector(`#${defCon.rndId}`) && document.querySelector(`.${defCon.rndClass}`)) { debug(`//-> Already Insert Button & CSS.`); } else { RAF(); } }); }; const opts = { childList: true, subtree: true }; let observer = new MutationObserver(callback); observer.observe(document, opts); /* Fonts selection */ const fontReady = await document.fonts.ready; const checkFont = new isSupportFontFamily(); const fontAvailable = new Set(); if (fontReady) { for (const font of fontCheck.values()) { if (checkFont.detect(font.en) || checkFont.detect(font.ch)) { fontAvailable.add(font); } } } const fontData = [...fontAvailable.values()]; if (document.querySelector(`#${defCon.rndId}`)) { fontSet("#fontSelect .font-list").fsearch("fontSelect", fontData); } /* Fonts stroke */ const strock = document.getElementById("strokeSize"); const drawStrock = new Progress("#stroke", { val: CONST.fontStroke * 100, size: 10, precision: 1, range: 1, drag: true, direction: "horizontal", tip: { trigger: "hover", align: "right", }, getVal: function (e) { strock.value = ((e.val / 100) * e.range).toFixed(e.precision + 2); }, }); drawStrock.onLoad(true, checkdraw(strock, drawStrock, /\d+(?:\.\d{1,3})?/)); /* Fonts shadow */ const shadows = document.getElementById("shadowSize"); let drawShadow = new Progress("#shadow", { val: (CONST.fontShadow * 100) / 8, size: 10, precision: 0, range: 8, drag: true, direction: "horizontal", tip: { trigger: "hover", align: "right", }, getVal: function (s) { shadows.value = ((s.val / 100) * s.range).toFixed(s.precision + 2); }, }); drawShadow.onLoad(false, checkdraw(shadows, drawShadow, /\d+(?:\.\d{1,2})?/)); /* Fonts shadow color selection */ const cpshow = document.querySelector("#color-picker-show"); const cp = document.querySelector("#color-picker"); const body = document.querySelector("body"); const colorshow = document.querySelector("#color"); let cpr = new ColorPicker(document.getElementById("slide"), document.getElementById("picker"), function ( hex, hsv, rgb, mousePicker, mouseSlide, currentColor ) { currentColor = hex; ColorPicker.positionIndicators( document.getElementById("slide-indicator"), document.getElementById("picker-indicator"), mouseSlide, mousePicker ); cpshow.style.backgroundColor = hex; colorshow.value = hex; colorshow.style.border = "2px solid #67a5df"; colorshow.style.color = "black"; }); cpr.setHex(CONST.shadowColor); const colorReg = /^currentcolor$|^#([A-F0-9]{6}|[a-f0-9]{6}|[A-F0-9]{3}|[a-f0-9]{3})$|^rgba\(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2([0-4][0-9]|5[0-5]))),\s*([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2([0-4][0-9]|5[0-5]))),\s*([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2([0-4][0-9]|5[0-5]))),\s*((?!1.[1-9])[0-1](\.[0-9])?)\)$|^rgb\(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2([0-4][0-9]|5[0-5]))),\s*([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2([0-4][0-9]|5[0-5]))),\s*([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2([0-4][0-9]|5[0-5])))\)$/; colorshow.addEventListener("change", function () { if (colorReg.test(this.value.trim())) { cpr.setHex(this.value); colorshow.style.border = "2px solid #67a5df"; colorshow.style.color = "black"; } else { colorshow.style.border = "2px solid red"; colorshow.style.color = "red"; } }); cpshow.addEventListener("click", function (e) { e.stopPropagation(); cp.style = "display:block"; }); cp.addEventListener( "click", function (e) { e.stopPropagation(); }, false ); body.addEventListener("click", function () { cp.style = "display:none"; }); /* Buttons control */ document.querySelector("#submitData .reset").addEventListener("click", async () => { let dialog = new DialogBox({ trueButtonText: "确 定", falseButtonText: "取 消", messageText: `

『重置』将初始化您所有的操作,脚本的所有参数将被还原为初始状态,一般是在您配置错误造成页面混乱后才会进行重置。

注意,重置后记得保存数据!

请确认您是否要进行重置操作?

`, titleText: "参数重置确认", }); if (await dialog.respond()) { fontSet().fdeleteList(fontData); strock.value = defValue.fontStroke.toFixed(3); drawStrock.updateVal((Number(defValue.fontStroke) * 100) / drawStrock.range); shadows.value = defValue.fontShadow.toFixed(2); drawShadow.updateVal((Number(defValue.fontShadow) * 100) / drawShadow.range); cpr.setHex(defValue.shadowColor); document.querySelector("#smooth").checked = defValue.fontSmooth; document.querySelector("#f-face").checked = defValue.fontFace; document.querySelector("#cssfun").value = defValue.fontCSS; document.querySelector("#exclude").value = defValue.fontEx; } dialog = null; }); document.querySelector("#submitData .fr-submit").addEventListener("click", async () => { const fstrock = /[0-9]+(?:\.[0-9]{1,3})?/.test(strock.value) ? strock.value : defValue.fontStroke; const fshadow = /[0-9]+(?:\.[0-9]{1,3})?/.test(shadows.value) ? shadows.value : defValue.fontShadow; const pickedcolor = colorshow.value; const fscolor = colorReg.test(pickedcolor) ? pickedcolor : defValue.shadowColor; const fontlists = fontSet().fsearchList("font-name"); const fontselect = fontlists.length > 0 ? String(fontlists.toString() + "," + defValue.fontSelect) : defValue.fontSelect; const smooth = document.querySelector("#smooth").checked; const fontface = document.querySelector("#f-face").checked; const fcss = document.querySelector("#cssfun").value; const cssfun = fcss ? fcss.toString() : defValue.fontCSS; const fex = document.querySelector("#exclude").value; const fontex = fex ? fex.toString() : defValue.fontEx; if ( saveDate("_fonts_set_", { fontSelect: fontselect, fontFace: fontface, fontStroke: fstrock, fontShadow: fshadow, shadowColor: fscolor, fontSmooth: smooth, fontCSS: cssfun, fontEx: fontex, }) ) { let dialog = new DialogBox({ trueButtonText: "感谢使用", messageText: "

您的设置参数已保存!页面将会自动刷新!

", titleText: "操作完毕", }); if (await dialog.respond()) { document.querySelector(`#${defCon.rndId}`).style = "visibility:hidden;"; dialog = null; location.reload(); } } else { let dialog = new DialogBox({ trueButtonText: "反馈问题", messageText: "

保存过程中发生了错误!

请收集浏览器信息、脚本插件信息、以及脚本版本后,与作者联系反馈!

", titleText: "错误报告", }); if (await dialog.respond()) { document.querySelector(`#${defCon.rndId}`).style = "visibility:hidden;"; window.open(feedback, "feedback"); } dialog = null; } }); document.querySelector("#submitData .cancel").addEventListener("click", () => { document.querySelector(`#${defCon.rndId}`).style = "display:none"; }); } catch (e) { error("%c[Error]%c\n%s", "font-weight:bold;color:red", "font-weight:bold;color:darkred", e); } /* SYSTEM INFO */ if (siteIndex === undefined) { let reFontFace = ""; fontCheck.forEach(item => { if (item.en.toLowerCase() === refont.toLowerCase()) { reFontFace = item.ch + " " + item.en; } }); console.info( `%c${defCon.scriptName}\n%c▞ 跨页面数据同步时长:%sms\n▞ 渲染字体:%s\n▞ 字体平滑:%s ▚ 字体重写:%s\n▞ 字体描边:%s ▚ 字体阴影:%s`, "line-height:160%;font-weight:bold;font-size:14px;color:red", "line-height:180%;font-size:12px;color:teal", refreshTime, reFontFace, CONST.fontSmooth ? "ON " : "OFF", CONST.fontFace ? "ON " : "OFF", Number(CONST.fontStroke) ? "ON " : "OFF", Number(CONST.fontShadow) ? "ON " : "OFF" ); } else { console.info( `%c${defCon.scriptName}\n%c${location.hostname.toUpperCase()} 已在排除渲染列表内,若要重新渲染,请在脚本菜单中打开重新渲染。`, "line-height:160%;font-weight:bold;font-size:14px;color:red", "line-height:180%;font-size:12px;color:darkred" ); } /* important Functions */ function addStyle(css, className, addToTarget, isReload, initType) { RAFInterval( () => { let addTo = document.querySelector(addToTarget); if (typeof addToTarget === "undefined") { addTo = document.head || document.body || document.documentElement || document; } isReload = isReload || false; initType = initType || "text/css"; if (typeof addToTarget === "undefined" || (typeof addToTarget !== "undefined" && document.querySelector(addToTarget) !== null)) { if (isReload === true) { safeRemove(`.${className}`); } else if (isReload === false && document.querySelector(`.${className}`) !== null) { return true; } const cssNode = document.createElement("style"); if (className !== null) { cssNode.className = className; } cssNode.setAttribute("type", initType); cssNode.innerHTML = css; try { addTo.appendChild(cssNode); } catch (e) { error(`//-> ${e.name}`); } return true; } return false; }, 200, true ); } function safeRemove(Css) { safeFunction(() => { const removeNodes = document.querySelectorAll(Css); for (let i = 0; i < removeNodes.length; i++) { removeNodes[i].remove(); } }); } function safeFunction(func) { try { func(); return true; } catch (e) { error(`//-> ${e.name}`); return false; } } function RAFInterval(callback, period, runNow) { const needCount = (period / 1000) * 60; let times = 0; if (runNow === true) { const shouldFinish = callback(); if (shouldFinish) { return; } } function step() { if (times < needCount) { times++; requestAnimationFrame(step); } else { const shouldFinish = callback() || false; if (!shouldFinish) { times = 0; requestAnimationFrame(step); } else { return; } } } requestAnimationFrame(step); } function saveDate(key, { ...Options }) { let obj = { ...Options }; try { GMsetValue(key, JSON.stringify(obj)); return true; } catch (e) { error(`//-> ${e.name}`); return false; } } })(); })();