Keldos
BREAKING (refactor): 完全重构整理css和js
9186425
raw
history blame
5.34 kB
// 为 bot 消息添加复制与切换显示按钮
function addChuanhuButton(botElement) {
var rawMessage = botElement.querySelector('.raw-message');
var mdMessage = botElement.querySelector('.md-message');
// var gradioCopyMsgBtn = botElement.querySelector('div.icon-button>button[title="copy"]'); // 获取 gradio 的 copy button,它可以读取真正的原始 message
if (!rawMessage) {
var buttons = botElement.querySelectorAll('button.chuanhu-btn');
for (var i = 0; i < buttons.length; i++) {
buttons[i].parentNode.removeChild(buttons[i]);
}
return;
}
var oldCopyButton = null;
var oldToggleButton = null;
oldCopyButton = botElement.querySelector('button.copy-bot-btn');
oldToggleButton = botElement.querySelector('button.toggle-md-btn');
if (oldCopyButton) oldCopyButton.remove();
if (oldToggleButton) oldToggleButton.remove();
// Copy bot button
var copyButton = document.createElement('button');
copyButton.classList.add('chuanhu-btn');
copyButton.classList.add('copy-bot-btn');
copyButton.setAttribute('aria-label', 'Copy');
copyButton.innerHTML = copyIcon;
copyButton.addEventListener('click', async () => {
const textToCopy = rawMessage.innerText;
try {
if ("clipboard" in navigator) {
await navigator.clipboard.writeText(textToCopy);
copyButton.innerHTML = copiedIcon;
setTimeout(() => {
copyButton.innerHTML = copyIcon;
}, 1500);
} else {
const textArea = document.createElement("textarea");
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
copyButton.innerHTML = copiedIcon;
setTimeout(() => {
copyButton.innerHTML = copyIcon;
}, 1500);
} catch (error) {
console.error("Copy failed: ", error);
}
document.body.removeChild(textArea);
}
} catch (error) {
console.error("Copy failed: ", error);
}
});
botElement.appendChild(copyButton);
// Toggle button
var toggleButton = document.createElement('button');
toggleButton.classList.add('chuanhu-btn');
toggleButton.classList.add('toggle-md-btn');
toggleButton.setAttribute('aria-label', 'Toggle');
var renderMarkdown = mdMessage.classList.contains('hideM');
toggleButton.innerHTML = renderMarkdown ? mdIcon : rawIcon;
toggleButton.addEventListener('click', () => {
renderMarkdown = mdMessage.classList.contains('hideM');
if (renderMarkdown){
renderMarkdownText(botElement);
toggleButton.innerHTML=rawIcon;
} else {
removeMarkdownText(botElement);
toggleButton.innerHTML=mdIcon;
}
});
botElement.insertBefore(toggleButton, copyButton);
function renderMarkdownText(message) {
var mdDiv = message.querySelector('.md-message');
if (mdDiv) mdDiv.classList.remove('hideM');
var rawDiv = message.querySelector('.raw-message');
if (rawDiv) rawDiv.classList.add('hideM');
}
function removeMarkdownText(message) {
var rawDiv = message.querySelector('.raw-message');
if (rawDiv) {
rawPre = rawDiv.querySelector('pre');
if (rawPre) rawDiv.innerHTML = rawPre.innerHTML;
rawDiv.classList.remove('hideM');
}
var mdDiv = message.querySelector('.md-message');
if (mdDiv) mdDiv.classList.add('hideM');
}
}
let timeoutId;
let isThrottled = false;
// 监听chatWrap元素的变化,为 bot 消息添加复制按钮。
var mObserver = new MutationObserver(function (mutationsList) {
for (const mmutation of mutationsList) {
if (mmutation.type === 'childList') {
for (var node of mmutation.addedNodes) {
if (node.nodeType === 1 && node.classList.contains('message')) {
saveHistoryHtml();
disableSendBtn();
document.querySelectorAll('#chuanhu-chatbot .message-wrap .message.bot').forEach(addChuanhuButton);
}
}
for (var node of mmutation.removedNodes) {
if (node.nodeType === 1 && node.classList.contains('message')) {
saveHistoryHtml();
disableSendBtn();
document.querySelectorAll('#chuanhu-chatbot .message-wrap .message.bot').forEach(addChuanhuButton);
}
}
} else if (mmutation.type === 'attributes') {
if (isThrottled) break; // 为了防止重复不断疯狂渲染,加上等待_(:з」∠)_
isThrottled = true;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
isThrottled = false;
document.querySelectorAll('#chuanhu-chatbot .message-wrap .message.bot').forEach(addChuanhuButton);
saveHistoryHtml();
disableSendBtn();
}, 1500);
}
}
});