Fix copy actions for non-HTTPS/localhost

Fixes #2352
This commit is contained in:
Cohee 2025-01-16 01:55:26 +02:00
parent 0441a8725f
commit 6e2b5d5dc8
2 changed files with 46 additions and 33 deletions

View File

@ -168,6 +168,7 @@ import {
isTrueBoolean, isTrueBoolean,
toggleDrawer, toggleDrawer,
isElementInViewport, isElementInViewport,
copyText,
} from './scripts/utils.js'; } from './scripts/utils.js';
import { debounce_timeout } from './scripts/constants.js'; import { debounce_timeout } from './scripts/constants.js';
@ -2315,17 +2316,16 @@ export function addCopyToCodeBlocks(messageElement) {
const codeBlocks = $(messageElement).find('pre code'); const codeBlocks = $(messageElement).find('pre code');
for (let i = 0; i < codeBlocks.length; i++) { for (let i = 0; i < codeBlocks.length; i++) {
hljs.highlightElement(codeBlocks.get(i)); hljs.highlightElement(codeBlocks.get(i));
if (navigator.clipboard !== undefined) {
const copyButton = document.createElement('i'); const copyButton = document.createElement('i');
copyButton.classList.add('fa-solid', 'fa-copy', 'code-copy', 'interactable'); copyButton.classList.add('fa-solid', 'fa-copy', 'code-copy', 'interactable');
copyButton.title = 'Copy code'; copyButton.title = 'Copy code';
codeBlocks.get(i).appendChild(copyButton); codeBlocks.get(i).appendChild(copyButton);
copyButton.addEventListener('pointerup', function (event) { copyButton.addEventListener('pointerup', async function () {
navigator.clipboard.writeText(codeBlocks.get(i).innerText); const text = codeBlocks.get(i).innerText;
await copyText(text);
toastr.info(t`Copied!`, '', { timeOut: 2000 }); toastr.info(t`Copied!`, '', { timeOut: 2000 });
}); });
} }
}
} }
@ -2724,7 +2724,7 @@ export function getStoppingStrings(isImpersonate, isContinue) {
export async function generateQuietPrompt(quiet_prompt, quietToLoud, skipWIAN, quietImage = null, quietName = null, responseLength = null, force_chid = null) { export async function generateQuietPrompt(quiet_prompt, quietToLoud, skipWIAN, quietImage = null, quietName = null, responseLength = null, force_chid = null) {
console.log('got into genQuietPrompt'); console.log('got into genQuietPrompt');
const responseLengthCustomized = typeof responseLength === 'number' && responseLength > 0; const responseLengthCustomized = typeof responseLength === 'number' && responseLength > 0;
let eventHook = () => {}; let eventHook = () => { };
try { try {
/** @type {GenerateOptions} */ /** @type {GenerateOptions} */
const options = { const options = {
@ -3390,7 +3390,7 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
const responseLengthCustomized = typeof responseLength === 'number' && responseLength > 0; const responseLengthCustomized = typeof responseLength === 'number' && responseLength > 0;
const isInstruct = power_user.instruct.enabled && api !== 'openai' && api !== 'novel' && !instructOverride; const isInstruct = power_user.instruct.enabled && api !== 'openai' && api !== 'novel' && !instructOverride;
const isQuiet = true; const isQuiet = true;
let eventHook = () => {}; let eventHook = () => { };
if (systemPrompt) { if (systemPrompt) {
systemPrompt = substituteParams(systemPrompt); systemPrompt = substituteParams(systemPrompt);
@ -5469,7 +5469,7 @@ async function promptItemize(itemizedPrompts, requestedMesId) {
} else { } else {
diffPrevPrompt.style.display = 'none'; diffPrevPrompt.style.display = 'none';
} }
popup.dlg.querySelector('#copyPromptToClipboard').addEventListener('click', function () { popup.dlg.querySelector('#copyPromptToClipboard').addEventListener('pointerup', async function () {
let rawPrompt = itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt; let rawPrompt = itemizedPrompts[PromptArrayItemForRawPromptDisplay].rawPrompt;
let rawPromptValues = rawPrompt; let rawPromptValues = rawPrompt;
@ -5477,7 +5477,7 @@ async function promptItemize(itemizedPrompts, requestedMesId) {
rawPromptValues = rawPrompt.map(x => x.content).join('\n'); rawPromptValues = rawPrompt.map(x => x.content).join('\n');
} }
navigator.clipboard.writeText(rawPromptValues); await copyText(rawPromptValues);
toastr.info(t`Copied!`); toastr.info(t`Copied!`);
}); });
@ -9507,7 +9507,7 @@ API Settings: ${JSON.stringify(getSettingsContents[getSettingsContents.main_api
//console.log(logMessage); //console.log(logMessage);
try { try {
await navigator.clipboard.writeText(logMessage); await copyText(logMessage);
toastr.info('Your ST API setup data has been copied to the clipboard.'); toastr.info('Your ST API setup data has been copied to the clipboard.');
} catch (error) { } catch (error) {
toastr.error('Failed to copy ST Setup to clipboard:', error); toastr.error('Failed to copy ST Setup to clipboard:', error);
@ -10572,24 +10572,18 @@ jQuery(async function () {
setTimeout(function () { $('#shadow_select_chat_popup').css('display', 'none'); }, animation_duration); setTimeout(function () { $('#shadow_select_chat_popup').css('display', 'none'); }, animation_duration);
}); });
if (navigator.clipboard === undefined) { $(document).on('pointerup', '.mes_copy', async function () {
// No clipboard support
$('.mes_copy').remove();
}
else {
$(document).on('pointerup', '.mes_copy', function () {
if (this_chid !== undefined || selected_group || name2 === neutralCharacterName) { if (this_chid !== undefined || selected_group || name2 === neutralCharacterName) {
try { try {
const messageId = $(this).closest('.mes').attr('mesid'); const messageId = $(this).closest('.mes').attr('mesid');
const text = chat[messageId]['mes']; const text = chat[messageId]['mes'];
navigator.clipboard.writeText(text); await copyText(text);
toastr.info('Copied!', '', { timeOut: 2000 }); toastr.info('Copied!', '', { timeOut: 2000 });
} catch (err) { } catch (err) {
console.error('Failed to copy: ', err); console.error('Failed to copy: ', err);
} }
} }
}); });
}
$(document).on('pointerup', '.mes_prompt', async function () { $(document).on('pointerup', '.mes_prompt', async function () {
let mesIdForItemization = $(this).closest('.mes').attr('mesId'); let mesIdForItemization = $(this).closest('.mes').attr('mesId');
@ -11483,4 +11477,3 @@ jQuery(async function () {
initCustomSelectedSamplers(); initCustomSelectedSamplers();
}); });

View File

@ -391,6 +391,26 @@ export function getStringHash(str, seed = 0) {
return 4294967296 * (2097151 & h2) + (h1 >>> 0); return 4294967296 * (2097151 & h2) + (h1 >>> 0);
} }
/**
* Copy text to clipboard. Use navigator.clipboard.writeText if available, otherwise use document.execCommand.
* @param {string} text - The text to copy to the clipboard.
* @returns {Promise<void>} A promise that resolves when the text has been copied to the clipboard.
*/
export function copyText(text) {
if (navigator.clipboard) {
return navigator.clipboard.writeText(text);
}
const parent = document.querySelector('dialog[open]:last-of-type') ?? document.body;
const textArea = document.createElement('textarea');
textArea.value = text;
parent.appendChild(textArea);
textArea.focus();
textArea.select();
document.execCommand('copy');
parent.removeChild(textArea);
}
/** /**
* Map of debounced functions to their timers. * Map of debounced functions to their timers.
* Weak map is used to avoid memory leaks. * Weak map is used to avoid memory leaks.