projang / Chess.com 익명 Embed 복사

// ==UserScript==
// @name         Chess.com 익명 Embed 복사
// @version      1.1
// @description  Chess.com 사이트에서 Embed 기보를 익명으로 복사하는 버튼을 추가합니다.
// @match        https://www.chess.com/game/live/*
// @match        https://www.chess.com/*/game/live/*
// @author       projang
// @license MIT
// @copyright 2021, projang (https://openuserjs.org/users/projang)
// @updateURL https://openuserjs.org/meta/projang/Chess.com_익명_Embed_복사.meta.js
// ==/UserScript==

document.querySelector("#sb > div:nth-child(3)").insertAdjacentHTML(
  "beforeend",
  `<a class="nav-link-component" id="copyembed">
<span class="nav-link-text">익명으로 복사</span>
</a>`
);

const copyElement = document.querySelector("#copyembed");
copyElement.onclick = copyAnonEmbed;

function copyAnonEmbed() {
  copyElement.style.color = "orangered";
  copyElement.text = "복사중";

  const game = document.querySelector("chess-board").game;
  const flipped = document
    .querySelector("chess-board")
    .game.getOptions().flipped;
  let pgn = game.getPGN();
  if (!pgn.includes("Termination")) {
    copyElement.text = "다시 시도하세요";
    return;
  }
  pgn = editPgnData(pgn, "White", "Anon");
  pgn = editPgnData(pgn, "Black", "Anon");
  pgn = editPgnData(pgn, "WhiteElo", "");
  pgn = editPgnData(pgn, "BlackElo", "");

  getEmbed(flipped, pgn).then((id) => {
    copyElement.style.color = "yellowgreen";
    const text = `<iframe id="${id}" allowtransparency="true" frameborder="0" style="width:100%;border:none;" src="//www.chess.com/emboard?id=${id}">`;
    copyToClipboard(text);
    copyElement.text = "복사 완료";
  });
}

async function getEmbed(flipped, pgnbody) {
  const data = JSON.stringify({
    "textSetup": "&-diagramtype:\nchessGame\n&-colorscheme:\ngreen\n&-piecestyle:\nneo\n&-float:\nleft\n&-flip:\n" +
      flipped +
      "\n&-prompt:\nfalse\n&-coords:\ntrue\n&-size:\n45\n&-hideglobalbuttons:\nfalse\n&-pgnbody:\n" +
      pgnbody,
  });
  return await fetch("https://www.chess.com/tinymce/api/get_diagram?id=new", {
    "headers": {
      "content-type": "application/json;charset=UTF-8",
    },
    "body": data,
    "method": "POST",
  }).then((res) => res.text());
}

function editPgnData(pgn, key, newValue) {
  const i = pgn.indexOf(key) + key.length + 2;
  return pgn.slice(0, i) + newValue + pgn.slice(pgn.indexOf('"', i));
}

function copyToClipboard(text) {
  var area = document.createElement("textarea");
  area.value = text;
  document.body.appendChild(area);

  area.select();
  document.execCommand("copy");
  document.body.removeChild(area);
}