Skip to content
quarry Artifact [33c3d6bacd]
Login

Artifact [33c3d6bacd]

Artifact 33c3d6bacdc9dc458455139d6aec27a7993273c8346d2e9b1072020c3318e76a:


// copy.js — the check-in page's "copy the full hash" button.
//
// This lived in an onclick attribute, which is inline script and the
// one thing a strict Content-Security-Policy cannot allow. Delegated
// from the document instead: one listener, no per-button wiring, and it
// keeps working for buttons that arrive in a patched fragment.
//
// Selection first, on purpose. Selecting the text is the fallback that
// always works — on a phone with no Clipboard API and no permission,
// the hash ends up selected and ready for the native copy gesture. The
// API is attempted after, and its failure changes nothing the reader
// can see except the confirmation.
(function () {
  "use strict";
  var RESET_MS = 5000;

  function confirmCopied(button) {
    var use = button.firstChild && button.firstChild.firstChild;
    button.classList.add("done");
    if (use) use.setAttribute("href", "#i-check");
    button.setAttribute("aria-label", "full hash copied");
    clearTimeout(button._resetTimer);
    button._resetTimer = setTimeout(function () {
      button.classList.remove("done");
      if (use) use.setAttribute("href", "#i-copy");
      button.setAttribute("aria-label", "copy the full hash");
    }, RESET_MS);
  }

  document.addEventListener("click", function (ev) {
    var button = ev.target.closest && ev.target.closest(".ci-copy");
    if (!button) return;
    var holder = button.parentNode && button.parentNode.nextElementSibling;
    var code = holder && holder.firstChild;
    if (!code) return;

    var selection = getSelection();
    var range = document.createRange();
    range.selectNodeContents(code);
    selection.removeAllRanges();
    selection.addRange(range);

    var copied = false;
    try {
      copied = document.execCommand("copy");
    } catch (e) {
      /* execCommand is gone or refused; the selection still stands. */
    }
    if (navigator.clipboard) {
      navigator.clipboard.writeText(code.textContent).then(
        function () { confirmCopied(button); },
        function () { if (copied) confirmCopied(button); }
      );
    } else if (copied) {
      confirmCopied(button);
    }
  });
})();