mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 20:54:14 +00:00
Improve legacy clipboard copy handling
Refactor ClipboardManager._legacyCopy to better handle focus and selection when copying. The textarea is now appended to the active element's parent (or body) and placed off-screen with aria-hidden and readonly attributes. The code preserves and restores the previous document selection and active element, uses focus({preventScroll: true}) to avoid scrolling, and returns the execCommand('copy') result. This makes legacy copy behavior more robust and less disruptive to the page state.
This commit is contained in:
parent
6a6a662a2e
commit
03aa619b91
1 changed files with 34 additions and 20 deletions
|
|
@ -550,31 +550,45 @@ export class ClipboardManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
static _legacyCopy(text) {
|
static _legacyCopy(text) {
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = text;
|
||||||
|
textarea.setAttribute('readonly', '');
|
||||||
|
textarea.setAttribute('aria-hidden', 'true');
|
||||||
|
textarea.style.position = 'absolute';
|
||||||
|
textarea.style.left = '-9999px';
|
||||||
|
textarea.style.top = '0';
|
||||||
|
textarea.style.opacity = '1';
|
||||||
|
|
||||||
|
const active = document.activeElement;
|
||||||
|
const host = (active && active !== document.body && active.parentElement)
|
||||||
|
? active.parentElement
|
||||||
|
: document.body;
|
||||||
|
host.appendChild(textarea);
|
||||||
|
|
||||||
|
const prevSelection = document.getSelection()?.rangeCount
|
||||||
|
? document.getSelection().getRangeAt(0)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
let ok = false;
|
||||||
try {
|
try {
|
||||||
const textarea = document.createElement('textarea');
|
textarea.focus({ preventScroll: true });
|
||||||
textarea.value = text;
|
|
||||||
textarea.setAttribute('readonly', '');
|
|
||||||
textarea.style.position = 'fixed';
|
|
||||||
textarea.style.top = '0';
|
|
||||||
textarea.style.left = '0';
|
|
||||||
textarea.style.width = '1em';
|
|
||||||
textarea.style.height = '1em';
|
|
||||||
textarea.style.padding = '0';
|
|
||||||
textarea.style.border = '0';
|
|
||||||
textarea.style.outline = 'none';
|
|
||||||
textarea.style.boxShadow = 'none';
|
|
||||||
textarea.style.background = 'transparent';
|
|
||||||
textarea.style.opacity = '0';
|
|
||||||
document.body.appendChild(textarea);
|
|
||||||
textarea.focus();
|
|
||||||
textarea.select();
|
textarea.select();
|
||||||
textarea.setSelectionRange(0, text.length);
|
textarea.setSelectionRange(0, text.length);
|
||||||
const ok = document.execCommand('copy');
|
ok = document.execCommand('copy');
|
||||||
document.body.removeChild(textarea);
|
|
||||||
return ok;
|
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host.removeChild(textarea);
|
||||||
|
if (active && typeof active.focus === 'function') {
|
||||||
|
try { active.focus({ preventScroll: true }); } catch { /* ignore */ }
|
||||||
|
}
|
||||||
|
if (prevSelection) {
|
||||||
|
const sel = document.getSelection();
|
||||||
|
sel?.removeAllRanges();
|
||||||
|
sel?.addRange(prevSelection);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue