MCPcopy Create free account
hub / github.com/coder/coder / simulateClipboardWrite

Function simulateClipboardWrite

site/src/hooks/useClipboard.ts:124–181  ·  view source on GitHub ↗

* Provides a fallback clipboard method for when browsers do not have access * to the clipboard API (the browser is older, or the deployment is only running * on HTTP, when the clipboard API is only available in secure contexts). * * It feels silly that you have to make a whole dummy input just t

(textToCopy: string)

Source from the content-addressed store, hash-verified

122 * @see {@link https://web.dev/patterns/clipboard/copy-text?hl=en}
123 */
124function simulateClipboardWrite(textToCopy: string): boolean {
125 const previousFocusTarget = document.activeElement;
126 const dummyInput = document.createElement("input");
127 // Keep the dummy input inside an open dialog so focus traps allow
128 // execCommand("copy") to select it.
129 const activeDialog =
130 previousFocusTarget instanceof HTMLElement
131 ? previousFocusTarget.closest(DIALOG_SELECTOR)
132 : undefined;
133 const dummyInputContainer =
134 activeDialog ?? document.querySelector(DIALOG_SELECTOR) ?? document.body;
135
136 // Have to add test ID to dummy element for mocking purposes in tests
137 dummyInput.setAttribute("data-testid", HTTP_FALLBACK_DATA_ID);
138
139 // Using visually-hidden styling to ensure that inserting the element doesn't
140 // cause any content reflows on the page (removes any risk of UI flickers).
141 // Can't use visibility:hidden or display:none, because then the elements
142 // can't receive focus, which is needed for the execCommand method to work
143 const style = dummyInput.style;
144 style.display = "inline-block";
145 style.position = "absolute";
146 style.overflow = "hidden";
147 style.clip = "rect(0 0 0 0)";
148 style.clipPath = "rect(0 0 0 0)";
149 style.height = "1px";
150 style.width = "1px";
151 style.margin = "-1px";
152 style.padding = "0";
153 style.border = "0";
154
155 dummyInputContainer.appendChild(dummyInput);
156 dummyInput.value = textToCopy;
157 dummyInput.focus();
158 dummyInput.select();
159
160 /**
161 * The document.execCommand method is officially deprecated. Browsers are free
162 * to remove the method entirely or choose to turn it into a no-op function
163 * that always returns false. You cannot make any assumptions about how its
164 * core functionality will be removed.
165 *
166 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Clipboard}
167 */
168 let copySuccessful: boolean;
169 try {
170 copySuccessful = document?.execCommand("copy") ?? false;
171 } catch {
172 copySuccessful = false;
173 }
174
175 dummyInput.remove();
176 if (previousFocusTarget instanceof HTMLElement) {
177 previousFocusTarget.focus();
178 }
179
180 return copySuccessful;
181}

Callers 1

useClipboardFunction · 0.85

Calls 1

removeMethod · 0.80

Tested by

no test coverage detected