Greasy Fork is available in English.
让牛牛聊天支持发送图片,发送任何外链图片链接时,自动转换为图片,可以点击查看大图
当前为
// ==UserScript==
// @name 牛牛聊天发图片插件
// @namespace https://www.milkywayidle.com/
// @version 0.1.2
// @description 让牛牛聊天支持发送图片,发送任何外链图片链接时,自动转换为图片,可以点击查看大图
// @match https://www.milkywayidle.com/*
// @match https://test.milkywayidle.com/*
// @grant GM_addStyle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
GM_addStyle(`
.chat-img {
display: inline-flex;
margin: 1px 4px;
max-height: 60px;
max-width: 100px;
width: fit-content;
border: 2px solid #778be1;
border-radius: 4px;
padding: 1px;
white-space: nowrap;
background: #000;
cursor: pointer;
}
.chat-img-preview {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
cursor: zoom-out;
}
.chat-img-preview img {
max-width: 90%;
max-height: 90%;
border: 2px solid #fff;
border-radius: 4px;
}
`);
const chatHistorySelector = 'div.ChatHistory_chatHistory__1EiG3';
const chatMessageSelector = 'div.ChatMessage_chatMessage__2wev4';
function isImageUrl(url) {// 检查链接是否是图片
return url && /\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?.*)?$/i.test(url);
}
function createPreviewOverlay(imgSrc) {//创建预览
const overlay = document.createElement('div');
overlay.className = 'chat-img-preview';
const previewImg = document.createElement('img');
previewImg.src = imgSrc;
overlay.appendChild(previewImg);
document.body.appendChild(overlay);
overlay.addEventListener('click', (e) => {// 点击后关闭图片预览
if (e.target === overlay || e.target === previewImg) {
document.body.removeChild(overlay);
}
});
document.addEventListener('keydown', function handleEsc(e) {// ESC关闭图片预览
if (e.key === 'Escape') {
document.body.removeChild(overlay);
document.removeEventListener('keydown', handleEsc);
}
});
}
function replaceLinkContentWithImage(link) {//修改A标签内的图片
const href = link.getAttribute('href');
if (!isImageUrl(href)) return;
if (link.querySelector('.chat-img')) return;
link.innerHTML = '';
const img = document.createElement('img');
img.src = href;
img.className = 'chat-img';
link.appendChild(img);
const newLink = link.cloneNode(true);//移除所有现有的事件监听器,用于屏蔽聊天URL确认框(@guch8017 提交)
link.parentNode.replaceChild(newLink, link);
newLink.addEventListener('click', (e) => {//改为插件的点击处理
e.preventDefault();
e.stopImmediatePropagation();
createPreviewOverlay(href);
});
}
function processExistingMessages(container) {//聊天页面消息处理
const messages = container.querySelectorAll(chatMessageSelector);
messages.forEach(msg => {
const links = msg.querySelectorAll('a');
links.forEach(replaceLinkContentWithImage);
});
}
function observeChatHistory(chatHistory) {//监听聊天页面变化
processExistingMessages(chatHistory);
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === Node.ELEMENT_NODE) {
const messages = node.matches(chatMessageSelector) ? [node] : node
.querySelectorAll(chatMessageSelector);
messages.forEach(msg => {
const links = msg.querySelectorAll('a');
links.forEach(replaceLinkContentWithImage);
});
}
});
});
});
observer.observe(chatHistory, {
childList: true,
subtree: true
});
}
function init() {
const chatHistories = document.querySelectorAll(chatHistorySelector);
if (chatHistories.length === 0) {
setTimeout(init, 1000);
return;
}
chatHistories.forEach(observeChatHistory);
const globalObserver = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === Node.ELEMENT_NODE) {
const newHistories = node.querySelectorAll?.(chatHistorySelector) || [];
newHistories.forEach(observeChatHistory);
}
});
});
});
globalObserver.observe(document.body, {
childList: true,
subtree: true
});
}
init();
})();