Spaces:
Sleeping
Sleeping
// 为 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); | |
} | |
} | |
}); | |