Copy button for outlinekeys

Adds a copy button for each access key in the listing

当前为 2025-08-13 提交的版本,查看 最新版本

// ==UserScript==
// @name        Copy button for outlinekeys
// @namespace   Violentmonkey Scripts
// @match       https://outlinekeys.com/
// @grant       GM.addStyle
// @grant       GM.getResourceText
// @version     1.0
// @require     https://unpkg.com/[email protected]/dist/notie.min.js
// @resource    notie-css https://unpkg.com/notie/dist/notie.min.css
// @description Adds a copy button for each access key in the listing
// @run-at      document-end
// @license MIT
// ==/UserScript==
GM.addStyle(GM.getResourceText("notie-css"));
document.querySelectorAll('a[href^="/key/"]').forEach(key => {
  const title = key.querySelector('h3');
  const copyButton = document.createElement('button');
  copyButton.type = 'button';
  copyButton.textContent = 'Copy';
  copyButton.className = 'btn btn-dark';
  copyButton.addEventListener('click', copyAccessKey);
  title.appendChild(copyButton);
})

async function copyAccessKey(event) {
  event.preventDefault();
  const button = event.target;
  const key = button.closest('a');
  const href = key.href;
  const title = key.querySelector('h3').firstChild;
  const icon = key.querySelector('img');
  const buttonText = event.target.textContent;
  event.target.textContent = 'Fetching...';
  const accessKey = await getAccessKey(href);
  if (document.hasFocus()) {
    finaly(accessKey)
  } else {
    window.addEventListener('focus', finaly.bind(null, accessKey), { once: true });
  }
  event.target.textContent = buttonText;

  function finaly(accessKey) {
    if (accessKey) {
      navigator.clipboard.writeText(accessKey);
      notie.alert({ type: 1, text: icon.outerHTML + title.textContent + ' copied', time: 1.5});
    } else {
      notie.alert({ type: 3, text: 'Error: Access key not found in the key page', time: 3});
    }
  }
}

async function getAccessKey(url) {
  const parser = new DOMParser();
  const res = await fetch(url);
  const src = await res.text();
  const doc = parser.parseFromString(src, 'text/html');
  const accessKey = doc.querySelector('#accessKey');
  return accessKey?.value;
}