summaryrefslogtreecommitdiff
path: root/docs/_static/js/codecopier.js
diff options
context:
space:
mode:
Diffstat (limited to 'docs/_static/js/codecopier.js')
-rw-r--r--docs/_static/js/codecopier.js13
1 files changed, 13 insertions, 0 deletions
diff --git a/docs/_static/js/codecopier.js b/docs/_static/js/codecopier.js
index 02143b92..4b0941c9 100644
--- a/docs/_static/js/codecopier.js
+++ b/docs/_static/js/codecopier.js
@@ -54,6 +54,16 @@ $(document).ready(async function () {
}) => {
const id = currentTarget.dataset.identifier
const divWithNeededId = $(`div[data-identifier='${id}']`)
+
+ // Per-click request token. Rapid re-clicks queue multiple writeText
+ // promises; without this guard, an older promise resolving later
+ // can overwrite the newer click's UI (or have its timeout fire on
+ // the new state). Each click increments the token, captures the
+ // local copy, and bails out of any UI/timeout work if the captured
+ // token no longer matches the current one.
+ const requestId = (divWithNeededId.data('copyRequestId') || 0) + 1
+ divWithNeededId.data('copyRequestId', requestId)
+
// Read from the .copyDiv's parentElement (the inner .highlight div it was
// injected into via insertAdjacentHTML('beforeend', ...)) rather than
// currentTarget.offsetParent — offsetParent depends on CSS positioning
@@ -75,17 +85,20 @@ $(document).ready(async function () {
try {
await navigator.clipboard.writeText(textToCopy)
+ if (divWithNeededId.data('copyRequestId') !== requestId) return
// Only flip the button into the success state when the write actually
// resolves — earlier versions showed "Copied!" even on failure.
divWithNeededId.addClass('copiedNotifier')
divWithNeededId.html('<span>Copied!</span>')
} catch (error) {
+ if (divWithNeededId.data('copyRequestId') !== requestId) return
console.error('Copying text failed, please try again', error)
divWithNeededId.addClass('copyFailedNotifier')
divWithNeededId.html('<span>Failed</span>')
}
const revertTimeout = setTimeout(() => {
+ if (divWithNeededId.data('copyRequestId') !== requestId) return
divWithNeededId.html(innersOfCopyDiv)
divWithNeededId.removeClass('copiedNotifier copyFailedNotifier')
divWithNeededId.removeData('revertTimeout')