mirror of
https://github.com/coder/coder.git
synced 2026-09-22 13:10:21 +08:00
revert: remove anti-flicker clipboard styling (#12227)
- These CSS changes were for making sure there weren't layout shifts when using the non-secure clipboard fallback, which could cause janky UI flickers. It seems to be breaking things for some users on HTTP-only connections, though.
This commit is contained in:
@@ -22,7 +22,14 @@ export const useClipboard = (textToCopy: string): UseClipboardResult => {
|
||||
setIsCopied(false);
|
||||
}, 1000);
|
||||
} catch (err) {
|
||||
const isCopied = simulateClipboardWrite(textToCopy);
|
||||
const input = document.createElement("input");
|
||||
input.value = textToCopy;
|
||||
document.body.appendChild(input);
|
||||
input.focus();
|
||||
input.select();
|
||||
const isCopied = document.execCommand("copy");
|
||||
document.body.removeChild(input);
|
||||
|
||||
if (isCopied) {
|
||||
setIsCopied(true);
|
||||
timeoutIdRef.current = window.setTimeout(() => {
|
||||
@@ -42,61 +49,3 @@ export const useClipboard = (textToCopy: string): UseClipboardResult => {
|
||||
|
||||
return { isCopied, copyToClipboard };
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 to simulate a
|
||||
* clipboard, but that's really the recommended approach for older browsers.
|
||||
*
|
||||
* @see {@link https://web.dev/patterns/clipboard/copy-text?hl=en}
|
||||
*/
|
||||
function simulateClipboardWrite(textToCopy: string): boolean {
|
||||
const previousFocusTarget = document.activeElement;
|
||||
const dummyInput = document.createElement("input");
|
||||
|
||||
// Using visually-hidden styling to ensure that inserting the element doesn't
|
||||
// cause any content reflows on the page (removes any risk of UI flickers).
|
||||
// Can't use visibility:hidden or display:none, because then the elements
|
||||
// can't receive focus, which is needed for the execCommand method to work
|
||||
const style = dummyInput.style;
|
||||
style.display = "inline-block";
|
||||
style.position = "absolute";
|
||||
style.overflow = "hidden";
|
||||
style.clip = "rect(0 0 0 0)";
|
||||
style.clipPath = "rect(0 0 0 0)";
|
||||
style.height = "1px";
|
||||
style.width = "1px";
|
||||
style.margin = "-1px";
|
||||
style.padding = "0";
|
||||
style.border = "0";
|
||||
|
||||
document.body.appendChild(dummyInput);
|
||||
dummyInput.value = textToCopy;
|
||||
dummyInput.focus();
|
||||
dummyInput.select();
|
||||
|
||||
/**
|
||||
* The document.execCommand method is officially deprecated. Browsers are free
|
||||
* to remove the method entirely or choose to turn it into a no-op function
|
||||
* that always returns false. You cannot make any assumptions about how its
|
||||
* core functionality will be removed.
|
||||
*
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Clipboard}
|
||||
*/
|
||||
let isCopied: boolean;
|
||||
try {
|
||||
isCopied = document?.execCommand("copy") ?? false;
|
||||
} catch {
|
||||
isCopied = false;
|
||||
}
|
||||
|
||||
dummyInput.remove();
|
||||
if (previousFocusTarget instanceof HTMLElement) {
|
||||
previousFocusTarget.focus();
|
||||
}
|
||||
|
||||
return isCopied;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user