<NME> copy.js
<BEF> function addCopyButtonCallbacks() {
  for (const el of document.getElementsByTagName("pre")) {
    const button = document.createElement("button");
    button.classList.add("copy-button", "fas", "fa-copy");
    el.appendChild(button);

    button.addEventListener("click", function () {
      navigator.clipboard.writeText(el.innerText).then(
        function () {
          button.classList.add("success", "fa-check");
          button.classList.remove("fa-copy");
        },
        function () {
          button.classList.add("error", "fa-times");
          button.classList.remove("fa-copy");
        }
      );

      setTimeout(function () {
        button.classList.add("fa-copy");

      setTimeout(function () {
        button.classList.add("fa-copy");
  }
}

if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks);
} else {
if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks);
} else {
  addCopyButtonCallbacks();
}

<MSG> Fix copy button JS for non-https contexts, fixes #1753. (#1754)


<DFF> @@ -4,17 +4,18 @@ function addCopyButtonCallbacks() {
     button.classList.add("copy-button", "fas", "fa-copy");
     el.appendChild(button);
 
+    const success = function () {
+      button.classList.add("success", "fa-check");
+      button.classList.remove("fa-copy");
+    };
+
+    const failure = function () {
+      button.classList.add("error", "fa-times");
+      button.classList.remove("fa-copy");
+    };
+
     button.addEventListener("click", function () {
-      navigator.clipboard.writeText(el.innerText).then(
-        function () {
-          button.classList.add("success", "fa-check");
-          button.classList.remove("fa-copy");
-        },
-        function () {
-          button.classList.add("error", "fa-times");
-          button.classList.remove("fa-copy");
-        }
-      );
+      copyToClipboard(el.innerText).then(success, failure);
 
       setTimeout(function () {
         button.classList.add("fa-copy");
@@ -24,6 +25,31 @@ function addCopyButtonCallbacks() {
   }
 }
 
+function copyToClipboard(text) {
+  // clipboard API is only available in secure contexts
+  if (window.navigator && window.navigator.clipboard) {
+    return window.navigator.clipboard.writeText(text);
+  } else {
+    return new Promise(function (resolve, reject) {
+      try {
+        const el = document.createElement("textarea");
+        el.textContent = text;
+        el.style.position = "fixed";
+        el.style.opacity = 0;
+        document.body.appendChild(el);
+        el.select();
+        document.execCommand("copy");
+
+        resolve();
+      } catch (err) {
+        reject(err);
+      } finally {
+        document.body.removeChild(el);
+      }
+    });
+  }
+}
+
 if (document.readyState === "loading") {
   document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks);
 } else {

Fix copy button JS for non-https contexts, fixes #1753. (#1754)