From 34ff8e239f580b0aa51307f091e529c13a71335d Mon Sep 17 00:00:00 2001 From: maver Date: Wed, 16 Oct 2024 19:33:05 +0200 Subject: [PATCH 1/3] Fix double double quotes when copying chat message text in Firefox --- public/script.js | 2 ++ public/scripts/browser-fixes.js | 52 +++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 public/scripts/browser-fixes.js diff --git a/public/script.js b/public/script.js index dff96074c..db6b0d5bf 100644 --- a/public/script.js +++ b/public/script.js @@ -247,6 +247,7 @@ import { AbortReason } from './scripts/util/AbortReason.js'; import { initSystemPrompts } from './scripts/sysprompt.js'; import { registerExtensionSlashCommands as initExtensionSlashCommands } from './scripts/extensions-slashcommands.js'; import { ToolManager } from './scripts/tool-calling.js'; +import { applyBrowserFixes } from './scripts/browser-fixes.js'; //exporting functions and vars for mods export { @@ -272,6 +273,7 @@ await new Promise((resolve) => { }); showLoader(); +applyBrowserFixes(); // Configure toast library: toastr.options.escapeHtml = true; // Prevent raw HTML inserts diff --git a/public/scripts/browser-fixes.js b/public/scripts/browser-fixes.js new file mode 100644 index 000000000..709077831 --- /dev/null +++ b/public/scripts/browser-fixes.js @@ -0,0 +1,52 @@ +const isFirefox = () => /firefox/i.test(navigator.userAgent); + +function sanitizeInlineQuotationOnCopy() { + // STRG+C, STRG+V on firefox leads to duplicate double quotes when inline quotation elements are copied. + // To work around this, take the selection and transform to before calling toString(). + document.addEventListener('copy', function (event) { + const selection = window.getSelection(); + if (selection.anchorNode.nodeName !== '#text' || selection.focusNode.nodeName !== '#text' || !selection.anchorNode?.parentElement.closest('.mes_text')) { + // Complex selection, skip. + return; + } + + const range = selection.getRangeAt(0).cloneContents(); + const tempDOM = document.createDocumentFragment(); + + function processNode(node) { + if (node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() === 'q') { + // Transform to , preserve children + const span = document.createElement('span'); + + [...node.childNodes].forEach(child => { + const processedChild = processNode(child); + span.appendChild(processedChild); + }); + + return span; + } else { + // Nested structures containing elements are unlikely + return node.cloneNode(true); + } + } + + [...range.childNodes].forEach(child => { + const processedChild = processNode(child); + tempDOM.appendChild(processedChild); + }); + + const newRange = document.createRange(); + newRange.selectNodeContents(tempDOM); + + event.preventDefault(); + event.clipboardData.setData('text/plain', newRange.toString()); + }); +} + +function applyBrowserFixes() { + if (isFirefox()) { + sanitizeInlineQuotationOnCopy(); + } +} + +export { isFirefox, applyBrowserFixes }; From f897a4ab1a0ca87e4afa50dfb3e926de057ec6ea Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:25:50 +0300 Subject: [PATCH 2/3] Merge with browser fixes from RossMods --- public/script.js | 5 ++--- public/scripts/RossAscends-mods.js | 24 +----------------------- public/scripts/browser-fixes.js | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/public/script.js b/public/script.js index db6b0d5bf..f39c58dc5 100644 --- a/public/script.js +++ b/public/script.js @@ -1,4 +1,4 @@ -import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter, addSafariPatch } from './scripts/RossAscends-mods.js'; +import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, initRossMods, shouldSendOnEnter } from './scripts/RossAscends-mods.js'; import { userStatsHandler, statMesProcess, initStats } from './scripts/stats.js'; import { generateKoboldWithStreaming, @@ -273,7 +273,6 @@ await new Promise((resolve) => { }); showLoader(); -applyBrowserFixes(); // Configure toast library: toastr.options.escapeHtml = true; // Prevent raw HTML inserts @@ -940,7 +939,7 @@ async function firstLoadInit() { throw new Error('Initialization failed'); } - addSafariPatch(); + applyBrowserFixes(); await getClientVersion(); await readSecretState(); await initLocales(); diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js index 69bd7c7a0..4e5f168b8 100644 --- a/public/scripts/RossAscends-mods.js +++ b/public/scripts/RossAscends-mods.js @@ -121,7 +121,7 @@ export function humanizeGenTime(total_gen_time) { */ var parsedUA = null; -function getParsedUA() { +export function getParsedUA() { if (!parsedUA) { try { parsedUA = Bowser.parse(navigator.userAgent); @@ -717,18 +717,6 @@ export const autoFitSendTextAreaDebounced = debounce(autoFitSendTextArea, deboun // --------------------------------------------------- -export function addSafariPatch() { - const userAgent = getParsedUA(); - console.debug('User Agent', userAgent); - const isMobileSafari = /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); - const isDesktopSafari = userAgent?.browser?.name === 'Safari' && userAgent?.platform?.type === 'desktop'; - const isIOS = userAgent?.os?.name === 'iOS'; - - if (isIOS || isMobileSafari || isDesktopSafari) { - document.body.classList.add('safari'); - } -} - export function initRossMods() { // initial status check checkStatusDebounced(); @@ -741,16 +729,6 @@ export function initRossMods() { RA_autoconnect(); } - if (isMobile()) { - const fixFunkyPositioning = () => { - console.debug('[Mobile] Device viewport change detected.'); - document.documentElement.style.position = 'fixed'; - requestAnimationFrame(() => document.documentElement.style.position = ''); - }; - window.addEventListener('resize', fixFunkyPositioning); - window.addEventListener('orientationchange', fixFunkyPositioning); - } - $('#main_api').change(function () { var PrevAPI = main_api; setTimeout(() => RA_autoconnect(PrevAPI), 100); diff --git a/public/scripts/browser-fixes.js b/public/scripts/browser-fixes.js index 709077831..322926171 100644 --- a/public/scripts/browser-fixes.js +++ b/public/scripts/browser-fixes.js @@ -1,3 +1,5 @@ +import { getParsedUA, isMobile } from './RossAscends-mods.js'; + const isFirefox = () => /firefox/i.test(navigator.userAgent); function sanitizeInlineQuotationOnCopy() { @@ -43,10 +45,34 @@ function sanitizeInlineQuotationOnCopy() { }); } +function addSafariPatch() { + const userAgent = getParsedUA(); + console.debug('User Agent', userAgent); + const isMobileSafari = /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); + const isDesktopSafari = userAgent?.browser?.name === 'Safari' && userAgent?.platform?.type === 'desktop'; + const isIOS = userAgent?.os?.name === 'iOS'; + + if (isIOS || isMobileSafari || isDesktopSafari) { + document.body.classList.add('safari'); + } +} + function applyBrowserFixes() { if (isFirefox()) { sanitizeInlineQuotationOnCopy(); } + + if (isMobile()) { + const fixFunkyPositioning = () => { + console.debug('[Mobile] Device viewport change detected.'); + document.documentElement.style.position = 'fixed'; + requestAnimationFrame(() => document.documentElement.style.position = ''); + }; + window.addEventListener('resize', fixFunkyPositioning); + window.addEventListener('orientationchange', fixFunkyPositioning); + } + + addSafariPatch(); } export { isFirefox, applyBrowserFixes }; From 82570ef31d86bce75d925a9c0d84f4781f1ec627 Mon Sep 17 00:00:00 2001 From: maver Date: Thu, 17 Oct 2024 18:55:17 +0000 Subject: [PATCH 3/3] Remove textnode checks before applying firefox double double qutoes fix --- public/scripts/browser-fixes.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/scripts/browser-fixes.js b/public/scripts/browser-fixes.js index 322926171..96eaa7402 100644 --- a/public/scripts/browser-fixes.js +++ b/public/scripts/browser-fixes.js @@ -7,8 +7,7 @@ function sanitizeInlineQuotationOnCopy() { // To work around this, take the selection and transform to before calling toString(). document.addEventListener('copy', function (event) { const selection = window.getSelection(); - if (selection.anchorNode.nodeName !== '#text' || selection.focusNode.nodeName !== '#text' || !selection.anchorNode?.parentElement.closest('.mes_text')) { - // Complex selection, skip. + if (!selection.anchorNode?.parentElement.closest('.mes_text')) { return; }