您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
모바일 페이지 지원
当前为
// ==UserScript== // @name 유아렐갤 말투 교정기 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 모바일 페이지 지원 // @author urlgall // @match */mini/board/lists/?id=sandboxurl* // @match */mini/board/view/?id=sandboxurl* // @match */mini/sandboxurl* // @grant none // @run-at document-idle // @license MIT // ==/UserScript== (function() { 'use strict'; const CHO = [ 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' ]; const JUNG = [ 'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ' ]; const JONG = [ '', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' ]; const H_START = 0xAC00; const J_COUNT = 21; const L_COUNT = 28; function fixText(t) { const urlR = /(https?:\/\/[^\s<>]+)/g; const tokens = []; let lI = 0; t.replace(urlR, (match, offset) => { const nUT = t.substring(lI, offset); if (nUT) tokens.push({ v: nUT }); tokens.push({ v: match, isU: true }); lI = offset + match.length; return match; }); if (lI < t.length) tokens.push({ v: t.substring(lI) }); let o = ''; tokens.forEach(token => { if (token.isU) { o += token.v; } else { const cleanedT = token.v.replace(/[.,]/g, ''); o += a(cleanedT); } }); return o; } function a(t) { let o = ''; let c = -1; let j = -1; const getCI = (char) => CHO.indexOf(char); const getJI = (char) => JUNG.indexOf(char); const getLI = (char) => JONG.indexOf(char); const compose = (c, j, l = 0) => { if (c === -1 || j === -1) return ''; const code = H_START + (c * J_COUNT * L_COUNT) + (j * L_COUNT) + l; return String.fromCharCode(code); }; for (let i = 0; i < t.length; i++) { const char = t[i]; const ci = getCI(char); const ji = getJI(char); const isJamo = (ci !== -1 || ji !== -1); if (!isJamo) { if (c !== -1 && j !== -1) { o += compose(c, j); } else if (c !== -1) { o += CHO[c]; } o += char; c = -1; j = -1; continue; } if (c === -1 && ci !== -1) { c = ci; } else if (c !== -1 && ji !== -1) { j = ji; const nc = (i + 1 < t.length) ? t[i + 1] : ''; const nli = getLI(nc); const anc = (i + 2 < t.length) ? t[i + 2] : ''; const anisj = getJI(anc) !== -1; if (nli > 0) { if (!anisj) { o += compose(c, j, nli); i++; c = -1; j = -1; } else { o += compose(c, j); c = -1; j = -1; } } else { o += compose(c, j); c = -1; j = -1; } } else { if (c !== -1 && j !== -1) { o += compose(c, j); c = -1; j = -1; } else if (c !== -1) { o += CHO[c]; c = -1; } if (ci !== -1) { c = ci; } else { o += char; } } } if (c !== -1 && j !== -1) { o += compose(c, j); } else if (c !== -1) { o += CHO[c]; } return o; } function fixTitles() { const titles = document.querySelectorAll('td.gall_tit a, span.title_subject, span.subjectin, span.tit'); titles.forEach(el => { const origT = el.textContent; const fixedT = fixText(origT); const isA = el.tagName === 'A'; if (origT !== fixedT) { if (isA) { const keepC = Array.from(el.children); const trimT = fixedT.trimStart(); const newTn = document.createTextNode(trimT); el.innerHTML = ''; keepC.forEach(child => el.appendChild(child)); el.appendChild(newTn); } else { el.textContent = fixedT.trim(); } } }); } function fixContents() { const writes = document.querySelectorAll('div.write_div, div.thum-txtin'); writes.forEach(div => { fixNodes(div); }); const comments = document.querySelectorAll('p.usertxt, p.txt'); comments.forEach(p => { fixNodes(p); }); } function fixNodes(el) { const w = document.createTreeWalker( el, NodeFilter.SHOW_TEXT, null, false ); let n; const updates = []; while (n = w.nextNode()) { if (n.parentNode && n.parentNode.nodeName !== 'SCRIPT' && n.parentNode.nodeName !== 'STYLE') { if (!n.parentNode.classList || (!n.parentNode.classList.contains('korean-fixer-wrapper'))) { updates.push(n); } } } updates.forEach(tn => { const origT = tn.nodeValue; if (!origT.trim()) return; const fixedT = fixText(origT); if (origT !== fixedT) { const parent = tn.parentNode; if (!parent) return; const newTn = document.createTextNode(fixedT); const span = document.createElement('span'); span.classList.add('korean-fixer-wrapper'); span.appendChild(newTn); parent.replaceChild(span, tn); } else { tn.nodeValue = origT.trimStart(); } }); } fixTitles(); fixContents(); const observer = new MutationObserver((m) => { let update = false; m.forEach(mutation => { if (mutation.type === 'childList') { Array.from(mutation.addedNodes).forEach(n => { if (n.nodeType === 1) { if (n.querySelector('td.gall_tit a') || n.querySelector('span.title_subject') || n.querySelector('span.subjectin') || n.querySelector('span.tit') || n.querySelector('div.write_div') || n.querySelector('div.thum-txtin') || n.querySelector('p.usertxt') || n.querySelector('p.txt')) { update = true; } } }); } }); if (update) { fixTitles(); fixContents(); } }); observer.observe(document.body, { childList: true, subtree: true }); })();