Merge pull request #2994 from artisticMink/fix-double-quotes Fix double double quotes when copying chat message text in Firefox
Signed| @@ -1,4 +1,4 @@ | ||
| 1 | 1 | import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js'; |
| 2 | 2 | import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js'; |
| 3 | 3 | import { |
| 4 | 4 | generateKoboldWithStreaming, |
| @@ -247,6 +247,7 @@ import { AbortReason } from './scripts/util/AbortReason.js'; | ||
| 247 | 247 | import { initSystemPrompts } from './scripts/sysprompt.js'; |
| 248 | 248 | import { registerExtensionSlashCommands as initExtensionSlashCommands } from './scripts/extensions-slashcommands.js'; |
| 249 | 249 | import { ToolManager } from './scripts/tool-calling.js'; |
| 250 | +import { applyBrowserFixes } from './scripts/browser-fixes.js'; | |
| 250 | 251 | |
| 251 | 252 | //exporting functions and vars for mods |
| 252 | 253 | export { |
| @@ -938,7 +939,7 @@ async function firstLoadInit() { | ||
| 938 | 939 | throw new Error('Initialization failed'); |
| 939 | 940 | } |
| 940 | 941 | |
| 941 | 942 | addSafariPatchapplyBrowserFixes(); |
| 942 | 943 | await getClientVersion(); |
| 943 | 944 | await readSecretState(); |
| 944 | 945 | await initLocales(); |
| @@ -121,7 +121,7 @@ export function humanizeGenTime(total_gen_time) { | ||
| 121 | 121 | */ |
| 122 | 122 | var parsedUA = null; |
| 123 | 123 | |
| 124 | 124 | export function getParsedUA() { |
| 125 | 125 | if (!parsedUA) { |
| 126 | 126 | try { |
| 127 | 127 | parsedUA = Bowser.parse(navigator.userAgent); |
| @@ -717,18 +717,6 @@ export const autoFitSendTextAreaDebounced = debounce(autoFitSendTextArea, deboun | ||
| 717 | 717 | |
| 718 | 718 | // --------------------------------------------------- |
| 719 | 719 | |
| 720 | -export function addSafariPatch() { | |
| 721 | - const userAgent = getParsedUA(); | |
| 722 | - console.debug('User Agent', userAgent); | |
| 723 | - const isMobileSafari = /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); | |
| 724 | - const isDesktopSafari = userAgent?.browser?.name === 'Safari' && userAgent?.platform?.type === 'desktop'; | |
| 725 | - const isIOS = userAgent?.os?.name === 'iOS'; | |
| 726 | - | |
| 727 | - if (isIOS || isMobileSafari || isDesktopSafari) { | |
| 728 | - document.body.classList.add('safari'); | |
| 729 | - } | |
| 730 | -} | |
| 731 | - | |
| 732 | 720 | export function initRossMods() { |
| 733 | 721 | // initial status check |
| 734 | 722 | checkStatusDebounced(); |
| @@ -741,16 +729,6 @@ export function initRossMods() { | ||
| 741 | 729 | RA_autoconnect(); |
| 742 | 730 | } |
| 743 | 731 | |
| 744 | - if (isMobile()) { | |
| 745 | - const fixFunkyPositioning = () => { | |
| 746 | - console.debug('[Mobile] Device viewport change detected.'); | |
| 747 | - document.documentElement.style.position = 'fixed'; | |
| 748 | - requestAnimationFrame(() => document.documentElement.style.position = ''); | |
| 749 | - }; | |
| 750 | - window.addEventListener('resize', fixFunkyPositioning); | |
| 751 | - window.addEventListener('orientationchange', fixFunkyPositioning); | |
| 752 | - } | |
| 753 | - | |
| 754 | 732 | $('#main_api').change(function () { |
| 755 | 733 | var PrevAPI = main_api; |
| 756 | 734 | setTimeout(() => RA_autoconnect(PrevAPI), 100); |
| @@ -0,0 +1,77 @@ | ||
| 1 | +import { getParsedUA, isMobile } from './RossAscends-mods.js'; | |
| 2 | + | |
| 3 | +const isFirefox = () => /firefox/i.test(navigator.userAgent); | |
| 4 | + | |
| 5 | +function sanitizeInlineQuotationOnCopy() { | |
| 6 | + // STRG+C, STRG+V on firefox leads to duplicate double quotes when inline quotation elements are copied. | |
| 7 | + // To work around this, take the selection and transform <q> to <span> before calling toString(). | |
| 8 | + document.addEventListener('copy', function (event) { | |
| 9 | + const selection = window.getSelection(); | |
| 10 | + if (!selection.anchorNode?.parentElement.closest('.mes_text')) { | |
| 11 | + return; | |
| 12 | + } | |
| 13 | + | |
| 14 | + const range = selection.getRangeAt(0).cloneContents(); | |
| 15 | + const tempDOM = document.createDocumentFragment(); | |
| 16 | + | |
| 17 | + function processNode(node) { | |
| 18 | + if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'q') { | |
| 19 | + // Transform <q> to <span>, preserve children | |
| 20 | + const span = document.createElement('span'); | |
| 21 | + | |
| 22 | + [...node.childNodes].forEach(child => { | |
| 23 | + const processedChild = processNode(child); | |
| 24 | + span.appendChild(processedChild); | |
| 25 | + }); | |
| 26 | + | |
| 27 | + return span; | |
| 28 | + } else { | |
| 29 | + // Nested structures containing <q> elements are unlikely | |
| 30 | + return node.cloneNode(true); | |
| 31 | + } | |
| 32 | + } | |
| 33 | + | |
| 34 | + [...range.childNodes].forEach(child => { | |
| 35 | + const processedChild = processNode(child); | |
| 36 | + tempDOM.appendChild(processedChild); | |
| 37 | + }); | |
| 38 | + | |
| 39 | + const newRange = document.createRange(); | |
| 40 | + newRange.selectNodeContents(tempDOM); | |
| 41 | + | |
| 42 | + event.preventDefault(); | |
| 43 | + event.clipboardData.setData('text/plain', newRange.toString()); | |
| 44 | + }); | |
| 45 | +} | |
| 46 | + | |
| 47 | +function addSafariPatch() { | |
| 48 | + const userAgent = getParsedUA(); | |
| 49 | + console.debug('User Agent', userAgent); | |
| 50 | + const isMobileSafari = /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); | |
| 51 | + const isDesktopSafari = userAgent?.browser?.name === 'Safari' && userAgent?.platform?.type === 'desktop'; | |
| 52 | + const isIOS = userAgent?.os?.name === 'iOS'; | |
| 53 | + | |
| 54 | + if (isIOS || isMobileSafari || isDesktopSafari) { | |
| 55 | + document.body.classList.add('safari'); | |
| 56 | + } | |
| 57 | +} | |
| 58 | + | |
| 59 | +function applyBrowserFixes() { | |
| 60 | + if (isFirefox()) { | |
| 61 | + sanitizeInlineQuotationOnCopy(); | |
| 62 | + } | |
| 63 | + | |
| 64 | + if (isMobile()) { | |
| 65 | + const fixFunkyPositioning = () => { | |
| 66 | + console.debug('[Mobile] Device viewport change detected.'); | |
| 67 | + document.documentElement.style.position = 'fixed'; | |
| 68 | + requestAnimationFrame(() => document.documentElement.style.position = ''); | |
| 69 | + }; | |
| 70 | + window.addEventListener('resize', fixFunkyPositioning); | |
| 71 | + window.addEventListener('orientationchange', fixFunkyPositioning); | |
| 72 | + } | |
| 73 | + | |
| 74 | + addSafariPatch(); | |
| 75 | +} | |
| 76 | + | |
| 77 | +export { isFirefox, applyBrowserFixes }; | |