返回首頁 

Greasy Fork is available in English.

中英文之间加空白

自动替你在网页中所有的中文字和半形的英文、数字、符号之间插入空白,让文字变得美观好看。(pangu, 盤古之白)


Installer ce script?
// ==UserScript==// @name                中英文之间加空白// @name:zh-TW          中英文之間加空白// @version             0.7.13// @author              CY Fung// @namespace           UserScript// @license             MIT// @require             https://cdn.jsdelivr.net/gh/cyfung1031/userscript-supports@b4f5e6fae19dd9f6d36b09054d0a3e4ef7e7eaa4/library/pangu-lite.js// @match               http://*/*// @match               https://*/*// @exclude             /^https?://\S+\.(txt|png|jpg|jpeg|gif|xml|svg|manifest|log|ini)[^\/]*$/// @exclude             /^shttps?://yuzu-emu.org/*$/// @icon                https://raw.githubusercontent.com/cyfung1031/userscript-supports/main/icons/blank-letter.png// @grant               GM_setValue// @grant               unsafeWindow// @run-at              document-start// @allFrames           true// @inject-into         content// @description         自动替你在网页中所有的中文字和半形的英文、数字、符号之间插入空白,让文字变得美观好看。(pangu, 盤古之白)// @description:zh-TW   自動替你在網頁中所有的中文字和半形的英文、數字、符號之間插入空白,讓文字變得美觀好看。(pangu, 盤古之白)// ==/UserScript==((__CONTEXT__) => {const { pangu } = __CONTEXT__;const win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : (this instanceof Window ? this : window);// Create a unique key for the script and check if it is already runningconst hkey_script = 'depcyxozwnig';if (win[hkey_script]) throw new Error('Duplicated Userscript Calling'); // avoid duplicated scriptingwin[hkey_script] = true;/** @type {globalThis.PromiseConstructor} */const Promise = (async () => { })().constructor; // YouTube hacks Promise in WaterFox Classic and "Promise.resolve(0)" nevers resolve.const cleanContext = async (win) => {const waitFn = requestAnimationFrame; // shall have been binded to windowtry {let mx = 16; // MAX TRIALconst frameId = 'vanillajs-iframe-v1'let frame = document.getElementById(frameId);let removeIframeFn = null;if (!frame) {frame = document.createElement('iframe');frame.id = frameId;const blobURL = typeof webkitCancelAnimationFrame === 'function' && typeof kagi === 'undefined' ? (frame.src = URL.createObjectURL(new Blob([], { type: 'text/html' }))) : null; // avoid Brave Crashframe.sandbox = 'allow-same-origin'; // script cannot be run inside iframe but API can be obtained from iframelet n = document.createElement('noscript'); // wrap into NOSCRPIT to avoid reflow (layouting)n.appendChild(frame);while (!document.documentElement && mx-- > 0) await new Promise(waitFn); // requestAnimationFrame here could get modified by YouTube engineconst root = document.documentElement;root.appendChild(n); // throw error if root is null due to exceeding MAX TRIALif (blobURL) Promise.resolve().then(() => URL.revokeObjectURL(blobURL));removeIframeFn = (setTimeout) => {const removeIframeOnDocumentReady = async (e) => {e && win.removeEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);e = n;n = win = removeIframeFn = 0;if (setTimeout) await new Promise(resolve => setTimeout(resolve, 200));try {e.remove();} catch (e) { }}if (!setTimeout || document.readyState !== 'loading') {removeIframeOnDocumentReady();} else {win.addEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);}}}while (!frame.contentWindow && mx-- > 0) await new Promise(waitFn);const fc = frame.contentWindow;if (!fc) throw "window is not found."; // throw error if root is null due to exceeding MAX TRIALtry {const { requestAnimationFrame, setTimeout, clearTimeout } = fc;const res = { requestAnimationFrame, setTimeout, clearTimeout };for (let k in res) res[k] = res[k].bind(win); // necessaryif (removeIframeFn) Promise.resolve(res.setTimeout).then(removeIframeFn);return res;} catch (e) {if (removeIframeFn) removeIframeFn();return null;}} catch (e) {console.warn(e);return null;}};cleanContext(win).then(__CONTEXT__ => {if (!__CONTEXT__) return null;const { requestAnimationFrame } = __CONTEXT__;let rafPromise = null;const getRafPromise = () => rafPromise || (rafPromise = new Promise(resolve => {requestAnimationFrame(hRes => {rafPromise = null;resolve(hRes);});}));class Mutex {constructor() {this.p = Promise.resolve()}lockWith(f) {this.p = this.p.then(() => new Promise(f).catch(console.warn))}}let busy = false;const mutex = new Mutex();function executor(f) {mutex.lockWith(unlock => {if (busy) {unlock();return;}busy = true;Promise.resolve().then(() => {f();}).then(() => {busy = false;}).then(unlock);});}let np_ = null;try {np_ = Object.getOwnPropertyDescriptor(Node.prototype, 'parentNode').get;} catch (e) { }const np = np_ || function () { return this.parentNode };np_ = null;const nativeContains = Node.prototype.contains;/** @param {Node} n */const myw = new Set();const addTheEvent = () => {document.addEventListener('DOMNodeInserted', function (e) {if (!busy) {myw.add(e.target);}}, { capture: false, passive: true });};let cachedTitle = null;function f77(commonParent_) {executor(() => {const node = commonParent_;if (node instanceof Node) {pangu.spacingNode(node);}});}const delayForSiteContentReady = (location.hostname.endsWith('nga.cn') || location.pathname.includes('/code')) ? getRafPromise : () => 0;async function onReady() {window.removeEventListener("DOMContentLoaded", onReady, false);let bodyDOM = null;try {bodyDOM = document.body;let maxLoopCount = 16;while (!bodyDOM && --maxLoopCount >= 0) {await getRafPromise();bodyDOM = document.body;}} catch (e) {bodyDOM = null;}if (!bodyDOM) return;if (await delayForSiteContentReady() !== 0) await new Promise(r => setTimeout(r, 177));executor(() => {pangu.spacingPageTitle();cachedTitle = document.title;pangu.spacingPageBody();});const config = {childList: true,subtree: true};let observer = null;function getCommonParent(elements) {let commonParent_ = null;try {for (n of elements) {// checking of body contains// 1. complete the algo logic// 2. prevent the element is added and then removed from the DOM treeif (nativeContains.call(document.body, n)) {if (commonParent_ === null) {commonParent_ = np.call(n);// myz.contains(n) === true} else if (commonParent_ instanceof Node) {let maxLooping = 600;while (!nativeContains.call(commonParent_, n) && --maxLooping > 0) { // worst case: myz = document.bodycommonParent_ = np.call(commonParent_);}if (maxLooping <= 0) commonParent_ = document.body; // rare case// myz.contains(n) === true}}}} catch (e) { commonParent_ = null; }return commonParent_;}const callback = async () => {let elements = null;if (myw.size > 0) {elements = [...myw];myw.clear();}Promise.resolve().then(() => {let cachedTitle_ = document.title;if (cachedTitle !== cachedTitle_) {cachedTitle = cachedTitle_;pangu.spacingPageTitle();cachedTitle = document.title;}});let tmp = false;try {if (elements) {const commonParent = await Promise.resolve(elements).then(getCommonParent)if (commonParent instanceof Node) f77(commonParent);}if (!observer) return;tmp = document.body;} catch (e) {}if (tmp != bodyDOM) {observer.takeRecords();observer.disconnect();if (tmp === false) {// Facebook - cross-frame errorobserver = null;bodyDOM = null;} else {bodyDOM = tmp;if (bodyDOM) {observer.observe(bodyDOM, config);callback();}}}};if (nativeContains && np) {addTheEvent();observer = new MutationObserver(callback);observer.observe(bodyDOM, config);}// callback();}Promise.resolve().then(() => {if (document.readyState !== 'loading') {onReady();} else {window.addEventListener("DOMContentLoaded", onReady, false);}});});})({ pangu });