// ==UserScript== // @name Namu Hot Now // @name:ko 나무위키 실검 알려주는 스크립트 // @namespace https://arca.live/b/namuhotnow // @version 0.9.0.11 // @description 이게 왜 실검? // @author KEMOMIMI // @match https://namu.wiki/* // @match https://arca.live/* // @connect arca.live // @icon https://www.google.com/s2/favicons?sz=64&domain=namu.wiki // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== function findLinkByPartialMatch(pairs, keyword) { for (let i = 0; i < pairs.length; i++) { let pair = pairs[i]; let text = pair.text; const regex = /<\/b>|]*>/g; var modifiedText = text.replace(regex, ''); if (modifiedText.toLowerCase().includes(keyword.toLowerCase())) { return [pair.link, pair.badges]; } } return [null, null]; } function getSpansContent() { var spansContent = []; var spans = Array.from(document.querySelectorAll('#app ul>li>a>span')).slice(0, 10); spans.forEach(function(span) { spansContent.push(span.textContent); }); return spansContent.join('').trim(); } var linkElements = []; var pairs = []; var previousSpansContent = ""; var storedElements = []; function removeLinkElements() { for (var i = 0; i < linkElements.length; i++) { var linkElement = linkElements[i]; linkElement.parentNode.removeChild(linkElement); } linkElements = []; } function checkMobileHotkewordOpened(){ const aTags = Array.from(document.querySelector('a[title="아무 문서로 이동"]').parentElement.querySelectorAll('a')); if (aTags.length > 10) { return true }else{ return false } } function checkMobileHotkeword(){ var chk = setInterval(function() { var svgTags = Array.from(document.querySelector('a[title="아무 문서로 이동"]').parentElement.querySelectorAll('svg')); if (svgTags.length<5) { var whyHotElements = document.querySelectorAll('.whyHot'); whyHotElements.forEach(function(element) { element.remove(); }); const elementsWithParentClass = document.querySelectorAll('.namuHotParentClass'); elementsWithParentClass.forEach(parentElement => { const childAElement = parentElement.querySelector('a'); if (childAElement) { parentElement.parentNode.insertBefore(childAElement, parentElement.nextSibling); parentElement.remove(); } }); }else if (svgTags.length>=5){ const elementsWithParentClass = document.querySelectorAll('.namuHotParentClass'); let count = 0; elementsWithParentClass.forEach(parentElement => { const childAnchorElements = parentElement.querySelectorAll('a'); childAnchorElements.forEach(anchorElement => { if (anchorElement.getAttribute('href') === '#') { count++; } }); }); if (count == 0) { const elementsWithParentClass = document.querySelectorAll('.namuHotParentClass'); elementsWithParentClass.forEach(function(element) { element.remove(); }); } if (elementsWithParentClass.length == 0) { if (checkMobileHotkewordOpened()) { clearInterval(chk); refreshLink(2); } } } }, 100); } //실검챈에서 게시물 링크를 수집하여 pairs에 저장하는 함수 //page : 긁어올 실검챈 페이지 길이 function updatePairs(page) { return new Promise((resolve, reject) => { let requests = []; for (var i = 1; i <= page; i++) { requests.push(new Promise((resolveRequest, rejectRequest) => { GM_xmlhttpRequest({ method: 'GET', url: 'https://arca.live/b/namuhotnow?p=' + i, onload: function(response) { const htmlData = response.responseText; const parser = new DOMParser(); const doc = parser.parseFromString(htmlData, 'text/html'); var elements = doc.querySelectorAll('.article-list .list-table a:not(.notice)'); storedElements = Array.from(elements); let pagePairs = []; elements.forEach(function(element) { const badgesElement = element.querySelector('.badges'); var badgesText = badgesElement ? badgesElement.textContent.trim() : '이왜실?'; var link = element.getAttribute('href'); var titleElement = element.querySelector('.table .title'); var text = titleElement ? titleElement.innerText.trim() : ''; pagePairs.push({text: text, link: link, badges: badgesText}); }); resolveRequest({page: i, pairs: pagePairs}); }, onerror: function(error) { rejectRequest(error); } }); })); } Promise.all(requests) .then(results => { // 페이지 정렬 results.sort((a, b) => a.page - b.page); // pairs 배열에 추가 results.forEach(result => { pairs.push(...result.pairs); }); // 수동 연결 항목 추가 pairs.push({ text: "나무위키 실검 알려주는 채널, 실검챈", link: "/b/namuhotnow/112775488", badges : "❗️공지"}); if(!GM_getValue('emojiDisplay', true)){ pairs.forEach(pair => { let index = 0; for (let i = 0; i < pair.badges.length; i++) { if (/[가-힣a-zA-Z]/.test(pair.badges[i])) { index = i; break; } } pair.badges = pair.badges.substring(index); }); } resolve(); }) .catch(error => { reject(error); }); }); } async function refreshLink(type) { try { await updatePairs(2); } catch (error) { console.error("업데이트 중 오류:", error); } if(type == 0){ var realtimeList = Array.from(document.querySelectorAll('#app ul>li>a>span')).slice(0, 10); realtimeList.forEach(function(titleElement) { var [resultLink, resultBadges] = findLinkByPartialMatch(pairs, titleElement.innerText.trim()); if (resultLink != null){ var linkElement = document.createElement('a'); linkElement.href = 'https://arca.live' + resultLink; linkElement.textContent = resultBadges; linkElement.display = 'flex'; linkElement.width = '40%'; linkElement.target="_blank"; linkElement.setAttribute('data-v-f1cb35f1', ''); linkElement.setAttribute('data-v-8eeb36ac', ''); linkElement.className = 'ECDfhgnB _6-LImOrz'; const parentLiTag = titleElement ? titleElement.parentElement.parentElement : null; parentLiTag.querySelector('a').style.width = "60%"; parentLiTag.appendChild(linkElement); linkElements.push(linkElement); } }); }else if(type == 1){ var firstLinkList = document.querySelector('aside .link-list'); var arcalinkElements = firstLinkList.querySelectorAll('a'); var titleArray = []; arcalinkElements.forEach(function(aLinkElement) { var [resultLink, resultBadges] = findLinkByPartialMatch(pairs, aLinkElement.getAttribute('title')); if(resultLink != null){ aLinkElement.style.paddingRight = "1em"; var newSpanHTML = `
${aLinkElement.getAttribute('title')}
`; aLinkElement.insertAdjacentHTML('beforebegin', newSpanHTML); aLinkElement.remove() } }); }else if(type == 2){ var namuHotParentClass = document.querySelectorAll('.namuHotParentClass'); if (!namuHotParentClass[0]) { const aTags = Array.from(document.querySelector('a[title="아무 문서로 이동"]').parentElement.querySelectorAll('a')); const mobileList = aTags.length > 10 ? aTags.slice(-10) : aTags; mobileList.forEach(function(element) { var [resultLink, resultBadges] = findLinkByPartialMatch(pairs, element.innerText.trim()); var newParent = document.createElement('span'); newParent.classList.add('namuHotParentClass'); if (resultLink != null){ var linkElement = document.createElement('a'); linkElement.href = 'https://arca.live' + resultLink; linkElement.textContent = resultBadges; linkElement.width = '20px'; linkElement.target="_blank"; linkElement.title = resultBadges; linkElement.setAttribute('data-v-f1cb35f1', ''); linkElement.setAttribute('data-v-8eeb36ac', ''); linkElement.className = 'ECDfhgnB _6-LImOrz whyHot'; linkElement.style.margin = "auto 5px"; element.style.width = "70%"; var beforePseudoElement = window.getComputedStyle(element, ':before'); element.parentNode.insertBefore(newParent, element); newParent.appendChild(element); newParent.appendChild(linkElement); newParent.style.display = 'flex'; linkElements.push(linkElement); }else{ element.parentNode.insertBefore(newParent, element); newParent.appendChild(element); element.style.width = "100%"; newParent.style.display = 'flex'; } }); checkMobileHotkeword(); } } } function isPC() { if ((window.innerWidth || document.documentElement.clientWidth) >= 1024) { return true; } else { return false; } } function appendStyle() { var style = document.createElement('style'); var css = ` ${[...Array(10)].map((_, i) => ` .namuHotParentClass:nth-of-type(${i + 1}) > a:nth-child(1):before { content: "${i + 1}." !important; }`).join('')} .whyHot { align-items: center; border: 1px solid transparent; border-radius: var(--nav-bar-child-radius-var); display: flex; padding: var(--search-box-suggest-item-gutter-y-var) var(--search-box-suggest-item-gutter-x-var); text-decoration: none; word-break: break-all; } `; style.appendChild(document.createTextNode(css)); document.head.appendChild(style); } function checkPopularSearchText() { const itemTitles = document.querySelectorAll('.item-title'); for (let title of itemTitles) { if (title.textContent.trim() === "인기검색어") { return true; } } return false; } (function() { 'use strict'; if (window.location.href.includes('namu.wiki')) { if(isPC()){ setInterval(function() { var content = getSpansContent(); if (content.length > 0 && previousSpansContent !== getSpansContent()) { previousSpansContent = getSpansContent(); removeLinkElements(); refreshLink(0); } }, 100); }else{ var interNamuMobile = setInterval(function() { if (checkMobileHotkewordOpened()) { clearInterval(interNamuMobile); appendStyle(); refreshLink(2); } }, 50); } } if (/arca.live\/b\/namuhotnow\/[0-9]+/.test(window.location.host + window.location.pathname)) { const spanElement = document.querySelector('span.badge.badge-success.category-badge'); var isNotice = false if (spanElement) { const textContent = spanElement.textContent.trim(); if (textContent.includes("공지")) { isNotice = true; } } if(!isNotice){ const titleElement = document.querySelector('.title-row > .title'); const titleOriginalText = titleElement.lastChild.data.trim(); var pattern = /.+\)\s.+/; var prefix = ""; var suffix = titleOriginalText; if (pattern.test(titleOriginalText)) { pattern = /^(.+)\)\s(.+)$/; const match = titleOriginalText.match(pattern); prefix = match[1]+") "; // "괄호부분) " suffix = match[2]; // "실검 키워드" } titleElement.removeChild(titleElement.lastChild); titleElement.appendChild(document.createTextNode("\n")); titleElement.appendChild(document.createTextNode(prefix)); suffix.split(', ').forEach((title, idx, array) => { var linkElement = document.createElement('a'); linkElement.href = 'https://namu.wiki/w/' + title; linkElement.textContent = title; linkElement.target="_blank" const element = document.querySelector('.containe-fluid.board-article'); if (element) { const bgColor = window.getComputedStyle(element).backgroundColor; const rgbValues = bgColor.match(/\d+/g); if (rgbValues && rgbValues.length >= 3) { const allAbove200 = rgbValues.slice(0, 3).every(value => Number(value) > 200); if (allAbove200){ linkElement.style.color = '#144c75'; // 진한 남색 }else{ linkElement.style.color = '#a8cfed'; // 연한 하늘색 } } else { console.log('RGB 값을 확인할 수 없습니다.'); } } else { console.log('해당 클래스를 가진 요소를 찾을 수 없습니다.'); } linkElement.style.cursor = 'pointer'; titleElement.appendChild(linkElement); if (idx + 1 < array.length) { titleElement.appendChild(document.createTextNode(", ")); } }); } } else if (window.location.href.includes('arca.live') && checkPopularSearchText()) { var intervalId = setInterval(function() { var firstLinkLista = document.querySelector('aside .link-list a'); if (firstLinkLista && firstLinkLista.innerHTML !== " ") { clearInterval(intervalId); refreshLink(1); } }, 50); } if(window.location.href.includes('arca.live/b/namuhotnow')){ fetch('https://search.namu.wiki/api/ranking') .then(response => response.json()) .then(data => { const rankings = {}; const emojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '️5️⃣', '6️⃣', '️7️⃣', '️8️⃣', '9️⃣', '🔟']; data.slice(0, 10).forEach((item, index) => { const emoji = emojis[index]; rankings[item] = emoji; }); const keywords = Object.keys(rankings).sort((a, b) => b.length - a.length); const titleElements = document.querySelectorAll('.table .title'); let reversedDict = Object.fromEntries( Object.entries(rankings).map(([key, value]) => [value, key]) ); titleElements.forEach(element => { let text = element.innerHTML; keywords.forEach(keyword => { if (text.toLowerCase().includes(keyword.toLowerCase())) { if (text.toLowerCase().indexOf(keyword.toLowerCase())){ let start = text.toLowerCase().indexOf(keyword.toLowerCase()); let end = start+keyword.length; //reversedDict[rankings[keyword]] = element.innerHTML.substring(start, end); text = text.slice(0, start)+`${rankings[keyword]}` + text.slice(end); } } }); for (const [key, value] of Object.entries(reversedDict)) { text = text.replace(key, `${key}${value}`); } element.innerHTML = text; }); }) .catch(error => console.error('Error:', error)); } if(window.location.href.includes('arca.live/b/namuhotnow/98121715')){ const settingTitle = document.createElement('h4'); settingTitle.textContent = '<스크립트 설정>'; const STORAGE_KEY = 'emojiDisplay'; const articleContents = document.querySelectorAll('.article-content'); const isEmojiDisplayed = GM_getValue(STORAGE_KEY, true); articleContents.forEach(articleContent => { const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = isEmojiDisplayed; const label = document.createElement('label'); label.textContent = '이모지 표시: '; label.appendChild(checkbox); articleContent.parentNode.insertBefore(settingTitle, articleContent); articleContent.parentNode.insertBefore(label, articleContent); checkbox.addEventListener('change', () => { GM_setValue(STORAGE_KEY, checkbox.checked); }); }); } })();