jQuery(function() { // Helper function to sanitize text formatting function cleanDokuWikiCodeSpaces(text) { return text .replace(/\r\n/g, '\n') // Standardize linebreaks .replace(/\n[ \u00A0]+(?=\n)/g, '\n') // Remove spaces sitting completely alone on a line .replace(/^[ \u00A0]+\n/, '\n') // Clean leading blank lines .replace(/\n[ \u00A0]+$/, '\n'); // Clean trailing blank lines } // FIX 1: Handle standard user manual mouse selections (Ctrl+C) document.addEventListener('copy', function(e) { const selection = window.getSelection(); if (selection.rangeCount > 0 && selection.anchorNode.parentElement.closest('pre.code')) { let cleanedText = cleanDokuWikiCodeSpaces(selection.toString()); e.clipboardData.setData('text/plain', cleanedText); e.preventDefault(); } }); // FIX 2: Handle DokuWiki Core's Native Async Copy Button document.addEventListener('click', function(e) { // Targets DokuWiki's core copy elements (like .button-copy or data targets) const btn = e.target.closest('button, a, div') && e.target.closest('[class*="copy"], [id*="copy"], [data-clipboard-target]'); if (!btn) return; // Force monitor the system clipboard immediately following the click let attempts = 0; const maxAttempts = 10; const checkAndCleanClipboard = setInterval(async () => { attempts++; try { let currentText = await navigator.clipboard.readText(); // If clipboard contains data and has the raw space error, rewrite it immediately if (currentText && (currentText.includes('\n ') || currentText.includes('\n\u00A0'))) { let cleanedText = cleanDokuWikiCodeSpaces(currentText); await navigator.clipboard.writeText(cleanedText); clearInterval(checkAndCleanClipboard); // Success, stop looping } } catch (err) { // Clipboard permissions might delay slightly, keep trying } if (attempts >= maxAttempts) { clearInterval(checkAndCleanClipboard); // Timeout safety fallback } }, 30); // Check every 30ms for immediate execution }); });