Fix iOS clipboard with contentEditable approach

- Try modern clipboard API first
- For iOS: use contentEditable + special range selection
- Set font-size 16px to prevent zoom on iOS
- Properly throw error on failure for user feedback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
b1rdmania
2025-12-29 12:53:55 +00:00
parent 46d78f42e3
commit 1eef11acbe
+37 -16
View File
@@ -679,40 +679,61 @@ class MotifApp {
}
private async copyToClipboard(text: string): Promise<void> {
// iOS Safari needs the textarea fallback - clipboard API is unreliable
// Try textarea approach first for better iOS compatibility
// Try modern clipboard API first
if (navigator.clipboard?.writeText) {
try {
await navigator.clipboard.writeText(text);
return;
} catch {
// Fall through to textarea method
}
}
// Fallback for iOS Safari and older browsers
const ta = document.createElement('textarea');
ta.value = text;
ta.style.position = 'fixed';
ta.style.left = '0';
ta.style.top = '0';
ta.style.opacity = '0';
ta.style.pointerEvents = 'none';
ta.setAttribute('readonly', ''); // Prevent keyboard on iOS
ta.style.left = '0';
ta.style.width = '2em';
ta.style.height = '2em';
ta.style.padding = '0';
ta.style.border = 'none';
ta.style.outline = 'none';
ta.style.boxShadow = 'none';
ta.style.background = 'transparent';
ta.style.fontSize = '16px'; // Prevent zoom on iOS
ta.setAttribute('readonly', '');
document.body.appendChild(ta);
// iOS specific selection
// iOS needs special handling
const isiOS = /ipad|iphone|ipod/i.test(navigator.userAgent);
if (isiOS) {
ta.contentEditable = 'true';
ta.readOnly = false;
const range = document.createRange();
range.selectNodeContents(ta);
const selection = window.getSelection();
if (selection) {
selection.removeAllRanges();
selection.addRange(range);
const sel = window.getSelection();
if (sel) {
sel.removeAllRanges();
sel.addRange(range);
}
ta.setSelectionRange(0, 999999);
} else {
ta.select();
}
ta.setSelectionRange(0, text.length); // iOS needs this
let success = false;
try {
success = document.execCommand('copy');
} catch {
success = false;
// ignore
}
document.body.removeChild(ta);
// Fallback to modern API if execCommand failed
if (!success && navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
if (!success) {
throw new Error('Copy failed');
}
}