MCPcopy Create free account
hub / github.com/coder/ghostty-web / copyToClipboard

Method copyToClipboard

lib/selection-manager.ts:845–892  ·  view source on GitHub ↗

* Copy text to clipboard

(text: string)

Source from the content-addressed store, hash-verified

843 * Copy text to clipboard
844 */
845 private async copyToClipboard(text: string): Promise<void> {
846 // First try: modern async clipboard API
847 if (navigator.clipboard && navigator.clipboard.writeText) {
848 try {
849 await navigator.clipboard.writeText(text);
850 return;
851 } catch (err) {
852 // Clipboard API failed (common in non-HTTPS or non-focused contexts)
853 // Fall through to legacy method
854 }
855 }
856
857 // Second try: legacy execCommand method via textarea
858 const previouslyFocused = document.activeElement as HTMLElement;
859 try {
860 // Position textarea offscreen but in a way that allows selection
861 const textarea = this.textarea;
862 textarea.value = text;
863 textarea.style.position = 'fixed'; // Avoid scrolling to bottom
864 textarea.style.left = '-9999px';
865 textarea.style.top = '0';
866 textarea.style.width = '1px';
867 textarea.style.height = '1px';
868 textarea.style.opacity = '0';
869
870 // Select all text and copy
871 textarea.focus();
872 textarea.select();
873 textarea.setSelectionRange(0, text.length);
874
875 const success = document.execCommand('copy');
876
877 // Restore focus
878 if (previouslyFocused) {
879 previouslyFocused.focus();
880 }
881
882 if (!success) {
883 console.error('❌ execCommand copy failed');
884 }
885 } catch (err) {
886 console.error('❌ Fallback copy failed:', err);
887 // Still try to restore focus even on error
888 if (previouslyFocused) {
889 previouslyFocused.focus();
890 }
891 }
892 }
893
894 /**
895 * Request a render update (triggers selection overlay redraw)

Callers 1

attachEventListenersMethod · 0.95

Calls 2

focusMethod · 0.45
selectMethod · 0.45

Tested by

no test coverage detected