From 34e4da1095726c6f9e4bb4272aa01b5a6dd43901 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sun, 4 Oct 2026 20:36:49 +0200 Subject: [PATCH] fix(ui): copy DNS record values on plain http instances On non-secure origins the copy button falls back to execCommand('copy') with a temporary textarea. The textarea was appended to , outside the x-trap focus trap of the DNS entries modal, so the trap pulled focus back and the selection was lost before the copy. The button showed success, but nothing was copied. Append the textarea next to the button, select it explicitly, and restore focus afterwards. "Copy all" now uses the shared copyButton handler instead of its own duplicate fallback that ignored failures. Closes #12075 --- resources/js/copy-button.js | 11 +++++-- .../shared/cloudflare-autoconfigure.blade.php | 30 ++----------------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/resources/js/copy-button.js b/resources/js/copy-button.js index 0ce8d5d67d..b62eaa120e 100644 --- a/resources/js/copy-button.js +++ b/resources/js/copy-button.js @@ -12,15 +12,22 @@ export function initializeCopyButtonComponent() { await navigator.clipboard.writeText(value); } else { // Deprecated, but the only copy path on plain http (non-secure contexts). + // The textarea goes next to the button, not into : a modal's x-trap + // pulls focus back from nodes outside it, which clears the selection. + const previousFocus = document.activeElement; const textarea = document.createElement('textarea'); textarea.value = value; textarea.setAttribute('readonly', ''); + textarea.setAttribute('tabindex', '-1'); textarea.style.position = 'fixed'; textarea.style.left = '-9999px'; - document.body.appendChild(textarea); + this.$el.after(textarea); + textarea.focus({ preventScroll: true }); textarea.select(); + textarea.setSelectionRange(0, textarea.value.length); const ok = document.execCommand('copy'); - document.body.removeChild(textarea); + textarea.remove(); + previousFocus?.focus?.({ preventScroll: true }); if (!ok) { throw new Error('Copy command was rejected.'); } diff --git a/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php b/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php index 8d102ff47f..9b565c4e98 100644 --- a/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php +++ b/resources/views/livewire/project/shared/cloudflare-autoconfigure.blade.php @@ -223,39 +223,15 @@ @if (filled($dnsCopyText)) -
+

{{ count($dnsHints) }} {{ count($dnsHints) === 1 ? 'entry' : 'entries' }} ยท BIND zone format