댓글에 있는 이미지 링크를 직접 이미지로 표시합니다.
当前为
// ==UserScript==
// @name 펨코 댓글 이미지 링크 이미지로 보기
// @namespace
// @version 1.0
// @description 댓글에 있는 이미지 링크를 직접 이미지로 표시합니다.
// @author ChatGPT
// @match *://*.fmkorea.com/*
// @grant none
// @namespace https://greasyfork.org/users/1394821
// ==/UserScript==
(function () {
'use strict';
const isDebugMode = false;
let isReplacing = false;
function debugLog(message) {
if (isDebugMode) {
console.log(message);
}
}
const imgRegex = /(https?:\/\/[^\s"'<>]+\.(?:png|jpg|jpeg|gif|webp))/gi;
// 텍스트 노드에서 이미지 링크를 찾아 변환하는 함수
function replaceImageLinks() {
if (isReplacing) {
debugLog("[fmk-comment-img] 이미지 변환 중이므로 중단");
return;
}
isReplacing = true;
debugLog("[fmk-comment-img] 이미지 변환 시작");
const commentWrapper = document.querySelector('#cmtPosition');
if (!commentWrapper) {
debugLog("[fmk-comment-img] 댓글 래퍼 요소를 찾을 수 없습니다.");
return;
}
const commentItems = commentWrapper.querySelectorAll('li');
debugLog(`[fmk-comment-img] 댓글 요소 수: ${commentItems.length}`);
commentItems.forEach((item, index) => {
debugLog(`[fmk-comment-img] ${index + 1}번째 댓글 처리 중...`);
const commentContent = item.querySelector('.comment-content');
if (!commentContent) {
debugLog(`[fmk-comment-img] ${index + 1}번째 댓글에 comment-content 요소가 없습니다.`);
return;
}
const xeContentDivs = commentContent.querySelectorAll('.xe_content');
xeContentDivs.forEach(xeContent => {
traverseTextNodes(xeContent);
});
});
isReplacing = false;
debugLog("[fmk-comment-img] 이미지 변환 완료");
}
// 텍스트 노드를 순회하면서 이미지 링크를 변환
function traverseTextNodes(element) {
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
let node;
while ((node = walker.nextNode())) {
const textContent = node.textContent;
const matches = [...textContent.matchAll(imgRegex)];
if (matches.length > 0) {
matches.forEach(match => {
const link = match[0];
const parent = node.parentElement;
// <a> 태그 안에 있는 텍스트인지 검사
if (parent.tagName.toLowerCase() === 'a' && parent.href === link) {
// <a> 태그 내부의 텍스트를 <img> 태그로 변경
const imgTag = `<img src="${link}" style="height:auto; object-fit:contain; display:inline-block; vertical-align:middle;">`;
parent.innerHTML = imgTag;
} else {
// 일반 텍스트 노드일 경우 <a> 태그로 감싸기
const imgTag = `<a onclick="return hs.expand(this)" href="${link}"><img src="${link}" style="height:auto; object-fit:contain; display:inline-block; vertical-align:middle;"></a>`;
const replacedText = textContent.replace(new RegExp(`(?<![href|src]=["'])${link}(?!["'])`, 'g'), imgTag);
const span = document.createElement('span');
span.innerHTML = replacedText;
node.replaceWith(span);
}
});
}
}
}
function observeCommentWrapper() {
const commentWrapper = document.querySelector('#cmtPosition');
if (!commentWrapper) {
debugLog("[fmk-comment-img] 댓글 래퍼 요소를 찾을 수 없습니다.");
return;
}
const observer = new MutationObserver((mutationsList) => {
mutationsList.forEach(mutation => {
if (mutation.target && mutation.target.classList.contains('xe_content')) {
debugLog("[fmk-comment-img] .xe_content 변경 감지됨");
replaceImageLinks();
}
});
});
observer.observe(commentWrapper, {
childList: true,
subtree: true,
});
debugLog("[fmk-comment-img] 댓글 래퍼 변경 감지 시작");
}
const style = document.createElement('style');
style.innerHTML = `
.comment-content img {
max-width: 12% !important;
height: auto !important;
}
@media (max-width: 768px) {
.comment-content img {
max-width: 30% !important; /* 모바일 화면에서 이미지 크기 30%로 설정 */
}
}
`;
document.head.appendChild(style);
replaceImageLinks();
observeCommentWrapper();
})();